Fork me on GitHub

类加载的时机

类加载到卸载的生命周期:加载->验证->准备->解析->初始化->使用->卸载
有5中情况必须对类立即进行初始化:
1. 遇到new getstatic putstatic invokestatic这四个字节码指令时,必须进行类初始化。使用到这几条指令的场景:使用new关键字实例化对象时;读取或者设置一个类的静态字段时,但是静态字段被final修饰除外,因为常量在编译时就存入了常量池;调用一个类的静态方法时。
2. 使用类的反射方法时,java.lang.reflect包里面的方法对类进行反射调用时。
3. 当初始化一个类时,发现其父类没有初始化则需要先进行初始化。
4. 当虚拟机启动时,包含main()方法类。虚拟机会先初始化这个类。
5. 使用JDK 1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandler实例最后解析结果是REF_getStatic REF_putstatic REF_invokeStatic 的方法句柄。
五种情景下的主动引用会出发类的初始化,所有的被动引用都不会触发初始化。
被动引用的三个例子:
1. 通过子类引用父类的静态字段,不会导致初始化。
2. 通过数组定义来引用类,不会触发类的初始化。
3. 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量类的初始化。 接口的加载过程与类稍有不同,接口中不能使用static{}代码块来初始化信息,但是编译器仍然会为其生成<clinit>()的构造器 ,当一个接口在初始化时不需要要求其父接口全部完成初始化,只有在真正使用到父接口的时候才会初始化,例如引用父接口中定义的常量。


最新评论

    还没有人评论...

当当

友情链接

Powered by Python. Copyright © 2017.

鄂ICP备17010875号. All rights reserved.