虚拟机的类加载的时机

来源:互联网 发布:手机上网数据自动关闭 编辑:程序博客网 时间:2024/05/21 21:50

之前讲过,在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。而虚拟机如何加载这些Class文件?

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

类加载的时机

类从被加载到虚拟机内存开始,到卸载出内存为止,整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)共7个阶段。其中验证、准备、解析3部分统称为连接(Linking),如下图所示:
这里写图片描述

其中加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,而解析阶段却不一定,它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定

什么情况下开始类加载的第一个阶段:加载?Java虚拟机并没有强制规定,但是对于初始化阶段,虚拟机规定了有且只有5种情况必须立即对类进行初始化(而加载、验证、准备自然需要在此之前):
1. 遇到new、gerstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先出发其初始化。生成这4条指令最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
2. 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有初始化,则需要先触发初始化。
3. 当初始化一个类,发现其父类还未初始化,则先触发其父类的初始化。
4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化那个类。
5. 当使用JDK1.7的动态语言支持,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

接口的初始化:只与上述的第3种不同,当一个接口初始化时,并不要求其父接口都完成了初始化,只有在真正用到父接口(如引用接口这定义的变量)才会初始化。

原创粉丝点击