【计算机基础】Java学习篇(二)深入了解JDK如何编译与运行

10.19-第二天

了解一个Java程序是如何在jdk上编译、执行是十分有必要的,而不是直接安装个IDE程序编程就行了。我们有必要理解其中的原理,理解PATH和CLASSPATH不是同一层级的环境变量,理解JVM是java程序唯一认识的操作系统,理解JVM的可执行文件为.class文档,理解IDE只是一种工具,它的很多设定和操作也是和JDK相互对应的,没有工具我们依然还会编程。以下的配置可以跟着配置和操作一遍,利于理解。然后再删除,因为实际上在jdk6以后的版本,我们无需配置CLASSPATH,在IDE中配置了JDK将会自动配置JAVA_HOME、PATH、CLASSPATH。我们知其所以然就可以了。

一、所有的一切从Hello World开始。

      首先,我们没有安装任何的应用程序,任何IDE,我们来写一段Hello World的程序。

      我们在桌面上新建一个记事本,取名叫HelloWorld.java,我们把这个文件的后缀名.txt改成.java(如果不显示需要在文件夹选项里设置显示文件后缀名)

      接着右键单击选择编辑,然后照着敲下面代码,反正也不知道什么意思。

public class HelloWorld {
   
 
}

       然后我们在大括号里接着敲。

public class HelloWorld{
	public static void main(String[] args){
		System.out.println("Hello World");
	}
}

       这样,就是一个完整的程序了,它可以实现一个功能就是显示(输出)Hello World。

       我们来了解一下这个程序,

       Java规定,所有的程序都要定义在类里面,而Class这个关键字(Keyword)就好像是一种声明,告诉你们我要定义一个类,类的名字在后面叫HelloWorld,而这个类名必须和咱们的文件名相同。(什么是类后面会介绍)

       同时我们也要注意字母的大小写,以及英文输入法的书写,空格必须用半角或Tab,这都是规定。

       然后大括号{},代表我们定义了一个区块(Block),区块里面包含了一个方法(Method),程序里面小括号前面就是方法名main,而main()方法的区块里包含了一句显示信息的程序代码,我们暂不了解是什么,这一句话其实就是一行程序指令,我们可以称之为描述(Statement),一句描述结束后要用分号。

       所有的程序执行都有一个起点,也就是程序进入点(Entry Point),规格书规定,这个main方法就是程序执行的起点,而且必须是这种形式照着写,日后我们就会明白每个关键词的意义。

 二、编译与PATH路径

        前面说了,Java程序要经过编译,变成.class文件才能被JVM所执行。而这个编译工具程序javac放在JDK的bin文件夹里。

        我们在命令提示符模式下,编译一下这个程序。   

  

我们用cd命令,这个命令是跳转的意思。空格Desktop跳转到下一级的Desktop文件夹去,这是什么,没错,这就是我们的桌面,我们的桌面就是一个文件夹,我们可以从c盘找到的,而我们新建的java文件也在这里。然后我们进行编译。

当什么都没显示的时候则说明编译成功了。这时你的桌面会多成来一个HelloWorld.class文件。

但更多情况是显示‘javac’不是内部或外部命令。这是怎么回事。原来这是因为javac这个命令,系统说我找不到。那怎么办,系统找不到那咱们就得帮它找,咱们需要自己指定javac的位置告诉系统。位置在哪?在bin文件夹里。

 

根据我安装的JDK位置,我找到了javac.exe(exe即可执行程序)的位置,只有17K大小。蓝标显示的是我们要记住的文件位置,可以Ctrl+C复制。回到命令提示符模式。

 我们把原来的javac指令替换成双引号指定位置的javac,这时再编译,则编译成功。

 

 那我们编译一个程序就要指定一次javac程序的位置会不会太麻烦了。有没有省事儿的办法呢。比如简写?

 此时此刻,我们需要了解一下,为什么系统不知道这个指令的位置,我们怎么告诉它呢,就好像是在教一个小孩子认路,这条路是去卧室,这条路是去厕所。这个原理就是,当我们输入一个指令的时候,计算机的操作系统它会去存储这些指令的位置信息的一个文件里面找,如果有,那就不用指定了,没有就不知道。我们把这些指令地址信息叫作PATH 环境变量,环境变量存储在注册表文件里,我们用Win+R,输入regedit即可打开注册表,在下面这个路径可以找到系统环境变量-PATH。

 

              我们也可以在命令提示符模式下,用指令去查看一下这个PATH环境变量都有什么。输入echo %PATH%

             

                那我们如何把这些编译工具添加到环境变量中呢?

                1、在命令提示符模式下,用SET指令设定。(但这种办法只能在这一个程序有效,关闭命令提示符模式再重开就会失效)

                      格式:SET PATH="路径";%PATH%

                      如:(把jdk中的bin目录路径写进去)

SET PATH="D:\Java\JDK\bin";%PATH%

 

                2、注册表,不太建议新手直接动注册表,这里的东西最好不要乱改,不然可能会引起系统崩溃。

                3、从Windows的环境变量中设置。这是最推荐的一种方式。

                右键桌面的计算机→属性→高级系统设置,在高级选项卡中有环境变量按钮,上面是用户变量,下面是系统变量。我们只改系统变量就可以了,用户变量只对系统的某一个用户有效。

                为了日后开发需要,我们新建一个系统变量取变量名叫JAVA_HOME,然后变量值写jdk的路径

                然后在系统变量中找到PATH然后选取、编辑写上%JAVA_HOME%\bin;,记得在结尾添加分号。建议把这个路径放到最前面,因为系统搜索PATH路径是按顺序的,如果你安装了多个jdk,也是按照顺序优先执行的。这个路径也就等同于jdk\bin

 

 

三、JVM与CLASSPATH

             程序已经编译好了,翻译成了位码,现在我们要交给JVM去执行了。启动JVM的指令是java,后面直接跟类名称就可以了。

 

  那我们想一下,如果我们换一个执行环境,比如我们没有cd到桌面,我们如何在其他环境执行这个文件,JVM又该怎么寻找这个位码文件呢?比如我们没有cd到Desktop直接执行。

  问题出现了,找不到。找不到HelloWorld这个主类。当然了,我们在其他的环境执行,JVM不知道路径当然找不到,还是老办法,找不到我们就得帮它找。肯定会有人说,那我们把这个文件路径指定出来是否可以呢。如果你自己亲自尝试你会发现也是不行的。

             那JVM到底去哪里找路径呢。

             答案是,JVM这个虚拟操作系统它会去CLASSPATH路径里搜索路径信息,这个应该也算java规定的。

             如果我们要在启动JVM并告知其可执行文件(.class)的位置,我们可以在命令提示符模式下用 -classpath或者缩写形式 -cp

这样也可以执行成功。前面之所以不用这样,是因为JVM预设的classpath就是读取当前文件夹的.class文件,如果自行设置则以你设定的为主。同样地,这个设定在你关闭命令提示符模式后即失效。

 

当然倘若你要经常使用到这个路径地址,你也可以把它设置在系统变量中,但不推荐这么做,我们暂时用IDE的自动配置classpath就开发即可,日后可以配置其他的路径。

 

四、JAR与CLASSPATH

          日后补充。我们的导包就和这个有关。

五、编译程序javac与CLASSPATH

           当我们在一个java程序中,使用了另一个java程序的类,我们编译和执行都需要用classpath来指定路径,多个路径用分号隔开。日后补充详细说明。

 

六、编译程序javac与SOURCEPATH

       

         现在我们可以在命令提示符模式下编译和运行程序了,但我们还需要进行管理,这么多源码和位码,我们需要分门别类。我们在桌面新建一个src文件夹目的是放源码,和一个classes文件夹目的是放位码。

        -sourcepath 这个指令的意思就是指定在一个文件夹寻找源码,-d 指定了编译完成后的位码存放文件夹

         比如 javac  -sourcepath src -d classes  src/HelloWorld.java ,的意思就是编译src/HelloWorld.java,如果需要用到其他源码从src文件夹下寻找,编译完指定送到classes里。

         我们还可以在编译的时候用 -verbose 自变量来查看编译的过程和细节,

         比如  javac -verbose -sourcepath src -d classes  src/HelloWorld.java

         我们可以清晰的看到编译的过程是,首先,先搜索-sourcepath指定的文件夹有没有我们需要用到的源码,然后会搜索CLASSPATH里是否有已经编译好的位码,因为没有指定所以默认目前路径,如果存在且源码没有改变则不需要编译,如果不存在则开始编译。

         如果我们指定了classpath,比如  javac -verbose -sourcepath src -cp classes -d classes  src/HelloWorld.java

         则会从classes这个路径寻找是否有相应的位码文件。

 

七、用package管理类

 

         现在我们能把源码和位码已经分开了,现在我们在看源码,我们编写不同的项目或者不同的模块就会有不同的源码,我们是不是应该把源码也进行一些分门别类。在Java语法里,有一个关键词叫做package(包),它可以实现文档分类,也可以区分类名称。比如两个package可以有相同的类名称有相同的HelloWorld.java,在两个包里就不会有冲突。

         关于使用package包管理会有一些规定。

         1、对于package的名字虽然没有硬性规定,但我们通常会以组织或单位的网址进行命名,比如若我的网址为facenoboy.com,则我的包名就会是com.facenoboy,由于网址都独一无二的这样具有唯一性。

         2、完全吻合名称(Fully Qualified Name),比如我们的HelloWorld.java文件放在了com.facenoboy这个包,那么完全吻合名称就是com.facenoboy.HelloWorld,在写java程序源码的时候,如果是同一个包,我们可以直接使用定义的类名,如果是不同包,我们就要使用这个完全吻合名称。

         那么当我们写程序时,完全吻合名称这么长,我们程序里用一次这个类就写这么多代码一定很麻烦,我们可以用另一个关键词import(导入)偷懒,我们可以在程序最前面导入这个包,就可以不用在别的程序写这么长了。比如 import com.facenoboy.HelloWorld,在别的程序中,我们就可以直接写HelloWorld类了,编译程序就会在编译的时候和import包进行比对。如果同一个包需要用到多个类,也可以直接写 import com.facenoboy.*,*号代表全部的意思。

         但import一定是万能的吗?

         其实不然,如果我们自己定义了一个类名和Java SE API里的类名冲突了,这样在我们编程序的时候,我们直接写类名,编译程序会很懵,不知道自己该用哪一个包,这种情况发生的时候,我们就必须规规矩矩的写全名称。切记不是所有情况都可以简写。

         在我们写程序的时候,比如HelloWorld,其实有很多Java SE API自带的类,比如System,之所以没有导入包也没有写全名称是因为,java.lang这个包由于过于常见,是可以直接使用的包。

 

八、使用了哪种JRE

       

        当JVM执行可执行文件的时候,会根据以下规则来寻找可用的JRE:

        1、可否在可执行文件的文件夹下找到相关的原生(Native)链接库

        2、可否在上一层目录找到JRE目录。

        当我们的PATH设置的是JDK的bin目录时,执行java指令的时候,JVM可以在bin上的上一层找到私有的JRE。一般当我们IDE配置了JDK以后,我们用的都是私有JRE。

 

九、类文档版本

        如果我们用JDK8编译以后,用JDK7的private jre7执行,可能会出现UnsupportedClassVersionError的错误

        日后详解。

 

十、IDE

       了解了JDK的编译过程,我们还是要回归到IDE环境中编程序的,毕竟一个集成的开发程序环境是多么的高效和方便。Eclipse在高校里大概是最常用的了,还有Intellij IDEA和NetBeans,由于我们只学习Java SE的部分,所以我选了NetBeans而没有选择Eclipse,当然了,不管使用哪种IDE,我们都应当熟悉和熟练的使用这个工具去开发我们的Java程序。

        具体IDE操作不详细说明了。自己探索。

猜你喜欢

转载自blog.csdn.net/qq_36042506/article/details/83002724