JVM中java类的加载时机
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制。
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸载(Unloading)七个阶段。其中验证、准备和解析三个部分统称为连接(Linking),如下如所示。
这七个阶段,加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类的加载过程必须按照这个顺序来按部就班地开始,而解析阶段则不一定,它在某些情况下可以在初始化阶段后再开始。
类的生命周期的每一个阶段通常都是互相交叉混合式进行的,通常会在一个阶段执行的过程中调用或激活另外一个阶段。
Java虚拟机规范没有强制性约束在什么时候开始类加载过程,但是对于初始化阶段,虚拟机规范则严格规定了有且只有四种情况必需立即对类进行“初始化”(而加载、验证、准备阶段则必需在此之前开始),这四种情况归类如下:
1.遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令最常见的Java代码场景是:使用new关键字实例化对象时、读取或者设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)时、以及调用一个类的静态方法的时候。
2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3.当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要触发父类的初始化。
4.当虚拟机启动时,用户需要指定一个执行的主类(包含main()方法的类),虚拟机会先初始化这个类。
对于这四种触发类进行初始化的场景,在java虚拟机规范中限定了“有且只有”这四种场景会触发。这四种场景的行为称为对类的主动引用,除此以外的所有引用类的方式都不会触发类的初始化,称为被动引用。
下面通过三个实例来说明被动引用:
示例1:
父类SuperClass.java public class SuperClass { static{ System.out.println("SuperClass init!"); } public static int value = 123; } 子类SubClass.java public class SubClass extends SuperClass { static{ System.out.println("SubClass init!"); } } 主类NotInitialization.java public class NotInitialization { public static void main(String[] args) { System.out.println(SubClass.value); } }
输出结果: SuperClass init! 123
由结果可以看出只输出了“SuperClass init!”,没有输出“SubClass init!”。这是因为对于静态字段,只有直接定义该字段的类才会被初始化,因此当我们通过子类来引用父类中定义的静态字段时,只会触发父类的初始化,而不会触发子类的初始化。
示例2:
SuperClass[ ] scs=new SuperClass[11];
如上,当初始化一个对象数组的时候,也不会触发类的初始化。
示例3:
public class ConstClass { static { system.out.printl("const"); } public static final int age =123; } public class NotInitialization{ public static void main(String[ ] args){ system.out.println(ConstClass.age); }
此时并不会出现 “const”,因为在NotInitialization类在编译的时候已经把ConstClass中的变量age放在常量池中了,访问时直接取出age即可,不会引发ConstClass的初始化。
阅读更多- java面试-深入理解JVM(八)——类加载的时机
- java中JVM加载类的时机
- JVM中java类的加载时机
- JVM中java类的加载时机
- java 类加载机制--类加载时机
- jvm系列(一):java类的加载机制
- Java 类加载时机和机制
- JVM(1):Java 类的加载机制
- java JVM 加载class的顺序
- 【java JVM】JVM中类的加载,加载class文件的原理机制
- Java学习之类加载全过程_JVM内存分析_反射机制核心原理_常量池理解
- Java JVM:编译加载与自定义类加载器
- 【转】jvm系列(一):java类的加载机制
- Java JVM:编译加载机制与自定义类加载器
- 【原创】对于纯Java项目,JVM 各个类加载器的加载目标是什么?
- 【深入浅出JAVA类加载和JVM】深入浅出JAVA类加载和JVM
- 在Eclipse中配置动态加载Class的JVM插件--JavaRebel
- JVM-类加载过程(Java类的生命周期)
- java Class 的加载时机
- 03-类加载器 分类: Java JVM 2015-07-24 23:46 122人阅读 评论(0) 收藏