Java程序的执行原理以及解释说明
在初学Java的时候,我们安装完Java的开发环境后,就可以通过记事本等编辑工具编写程序了。推荐在Windows操作系统中使用EditPlus工具进行编写。由于我使用的是Mac OS,所以,我使用Sublime Text编辑工具进行编写。
下面我们通过文本编辑工具写一个入门的“问世”程序:
HelloWorld.java
public class HelloWorld{
public static void main(String[] args){
System.out.println("HelloWorld");
}
}
下面所写的内容都将以上面的程序为例,以Mac OS系统为操作环境。
Java的加载与执行
Java程序的运行包括两个阶段:编译阶段和运行阶段。
1. 编译阶段
这个阶段的主要任务是检查Java源程序是否符合Java语法,符合Java语法规则则能够生成正常的字节码文件(xxx.class);不符合Java语法规则则无法生成字节码文件,并报出相应的错误。
编译阶段的过程:程序员需要创建一个以“.java”为扩展名的文件,该文件成为java源文件,源文件当中编写的内容是Java源代码/源程序,而这个源程序是不能随意编写的,必须符合Java语法规则,然后Java程序员需要使用JDK当中自带的javac命令对程序进行编译。
javac的使用规则:javac java源文件的路径
下面我们可以运行一下:
图1.png通过上图的命令,会生成HelloWorld.class文件,如下图:
图2.png注意:
- 字节码文件不是纯粹的二进制,这种文件无法直接在操作系统中执行,它是一种被Java虚拟机识别的机器码指令,通过Java虚拟机在操作系统中执行。
- 字节码文件是最终要执行的文件,所以说class文件生成之后,java源文件删除并不会影响java程序的执行。但是一般java源程序不要删除,因为class文件最终执行效果可能不是我们想要的,那个这个时候需要回头再重新修改java源文件,然后将java源程序重新编译生成新的class文件,然后再运行这个class程序,生成新的效果。
- javac是一个java编译器工具/命令。
- 一个源文件可以编译生成多个class文件,class文件的命名是根据类名命名的;
- 测试javac命令是否可用:javac -version,这也是检查编译器版本的命令。
2. 运行阶段
在编译阶段生成字节码文件后,我们就需要运行字节码文件执行最后的一步。
该阶段通过使用java命令实现。
java命令的使用规则:java 类名
运行阶段的过程:通过cd命令进入字节码文件所在的目录,然后执行java 类名命令。
下面我们看一下:
图3.png
通过上图,可以看到最终打印出“HelloWorld”这句话,就说明运行成功。
注意:
- 测试java命令是否可用:java -version,这也是检查Java虚拟机版本的命令;
- 在运行阶段,我们必须先进入字节码文件所在的目录,否则会报错,原因我们会在下面将要介绍的执行原理中介绍;
- java命令后面跟的是类名,不是路径,就像我们现在举例HelloWorld.java文件,它的类名是HelloWorld。
Java的执行过程以及原理
- 通过执行java命令,会先启动JVM;
- JVM启动后,JVM会去启动“类加载器ClassLoader”;
类加载器的作用:加载类的。本质上类加载器负责去硬盘上找“类”对应的“字节码”文件,以java HelloWorld为例,那么类加载器会去硬盘上搜索“HelloWorld.class”文件;
- 类加载器如果在硬盘上找不到相应的字节码文件,会报错:
错误: 找不到或无法加载主类 Test
类加载器如果在硬盘上找到了对应的字节码文件,类加载器会将该字节码文件装载到JVM当中,JVM启动“解释器”将字节码解释成“1001110...”这种二进制码,操作系统执行二进制码和硬件交互。
注意:
默认情况下,类加载器会去硬盘中当前路径下找字节码文件,这里就是为什么使用java命令执行之前,需要进入字节码文件所在的目录下,否则会报错。
下面是整个程序编译和运行两个阶段的逻辑图:
问题:能不能给类加载器指定一个路径,让类加载器去指定的路径下加载字节码文件呢?
答案是可以,但是需要设置环境变量classpath。
classpath是给类加载器指路的,属于Java特有的,我们如果配置了classpath后,类加载器只能在配置的路径下查找字节码文件,不再再当前路径下查找了。所以,我们不需要配置环境变量classpath,每次执行的时候,需要切换到字节码文件所在的路径在,然后运行。
Java程序的解释说明
- public:公共的;
- class:修饰类的关键字;
- HelloWorld:我们给类定义的名字,也叫类名;
- static:静态的;
- void:返回参数类型为void,表示可以不返回参数;
- main():main方法;
- public static void main(String[] args):这是固定写法,叫做main方法,也叫做主方法,是程序的入口。JVM在执行程序的时候,会主动去找main方法,没有这个规格的写法,程序是无法执行的。其中:String[] args是main方法的形式参数,args可以改变,对于主方法来说,只有这个地方可以改变,其他地方都是固定写法。
public class和class的区别
- 在一个类中,可以定义多个class类;
- 类不是必须要public修饰的,可以没有public;
- 在源文件中,只要有一个class类,编译后,必然会对应生成一个class文件,如果在一个类中,定义多个class类,编译后,也会相对应的生成多个class文件;
- public修饰的类可以没有,如果有的话,有且只有一个,public修饰的类名必须和源文件保持一致;
- 每个类都可以编写入口,执行的时候,java 具体某个类,这样就可以。但是一般一个软件只有一个入口,不会出现多个,所以,这里只适用于测试;
- 当在命令窗口中执行java HelloWorld,那么HelloWorld.class当中必须有主方法,没有主方法,虽然会编译通过,但是运行阶段会报错。
以上就是这篇文章的内容!