JVM是如何执行.class文件的?

 

简略过程:

 

详细过程:

1.类加载

当我们运行java.exe命令执行某个java程序时,由于java程序本身以.class字节码的形式存在,它不是一个可执行文件,所以需要JVM将类文件加载到内存中。

JVM中有三个类加载器:根类加载器、扩展类加载器和系统类加载器(也叫应用加载器)。根类加载器是C++实现的,扩展类加载器和应用加载器都是java语言实现的。

类的class文件读入内存后,就会创建一个java.lang.Class对象,一旦某个类被载入JVM中,同一个类就不会再次被载入。

一个类加载后,对应的Class对象,可以通过该类的实例的getClass()方法获得,Class对象有一个getClassLoader()方法,可以得到加载该类所用的类加载器。

2.连接

当类被加载后,系统就会位置创建一个对应的Class对象,接着进入连接阶段,连接又分为以下三个阶段:

2.1 校验:检验被加载的类是否有正确的内部结构,并和其他类协调一致。

2.2 准备:负责为类的静态属性分配内存,并设置默认初始值。注意:必须是静态属性!因为此时并不存在实例对象,设置值也是默认值初始值,而不是人为给定的值。

2.3 解析:将类的二进制数据中的符号引用替换成直接引用。

3.初始化

JVM负责对类进行初始化,也就是对静态属性进行初始化。java中对静态属性指定初始值的方式有两种:①声明静态属性时指定初始值;②使用静态初始化快为静态属性指定初始值。

需要注意的是JVM对一个类初始化时如果该类的父类没有被初始化,则会先初始化其父类,如果直接父类还有父类,那么会先初始化父类的父类,以此类推。所以,JVM最先初始化的总是java.lang.Object类,

当程序主动使用任何一个类时,系统会保证该类以及它的所有父类都会被初始化。

当java程序首次通过下面的六种方式来使用某个类或者接口时,系统就会初始化该类或者接口:

♦创建类的实例

♦调用某个类的静态方法

♦访问某个类或接口的静态属性,或者为静态属性赋值

♦使用反射方式强制创建某个类或接口对应的java.lang.Class对象

♦初始化某个类的子类

♦直接用java.exe命令运行某个主类。