`

《虚拟机类加载机制》笔记:类加载的时机

阅读更多

      周志明先生所著的《深入理解Java虚拟机:JVM高级特性与最佳实践》(购买地址:亚马逊链接),对我学习Java、理解Java之道有非常大的帮助。至今已读过两遍,为了能够融会贯通,加深记忆(人老了记忆力差),便在Blog上记录一些认为该记的东西。

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

       类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)七个阶段。



“解析”阶段不一定按照上图的顺序开始,它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称动态绑定或晚期绑定)

       虚拟机规范中并没有强行约束什么情况下需要开始类加载过程的第一个阶段(加载)。但是对于初始化阶段,虚拟机规范则是严格规定了有且只有四种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始)

          1、遇到newgetstaticputstaticinvokestatic4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象、读取或设置一个类的静态字段(final修饰、已在编译期把结果放入常量池的静态字段除外),以及调用一个类的静态方法的时候。

          2、使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有初始化,则初始化。

          3、当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发父类的初始化。

          4、当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的类),虚拟机会先初始化这个主类。

对于这四种会触发类进行初始化的场景,虚拟机规范中使用了一个很强烈的限定语“有且只有”,这四种场景中的行为被称为对一个类进行主动引用。除此之外所有引用类的方式,都不会触发初始化,称为被动引用。被动引用如以下的代码所示:

 

public class SuperClass {
	static {
	        System.out.println("superclass init");
	}
	public static int value=123;
}
public class SubClass extends SuperClass{
	static {
		System.out.println("subclass init");
	}
}
public class Test {
	public static void main(String[] args) {
               //以下不会触发SubClass的初始化。对于静态字段,只有直接定义这个字段的类才会被               //初始化。所以这里,只有父类被初始化。
	       System.out.println(SubClass.value);
	}
}
public class Test {
	public static void main(String[] args) {
		//这里并没有直接引用SuperClass类,而是用到了另一个类型(代表一个以SuperClass                //为元素类型的数组)
		SuperClass[] sca=new SuperClass[10];
	}
}

 

public class ConstClass {
	static {
		System.out.println("ConstClass init");
	}
	public static final String HELLOWORLD="hello world";
}
public class Test {
	public static void main(String[] args) {
		//虽然在这里的代码中引用了ConstClass中的常量HELLOWORLD,但是在编译阶段已将
		//此常量的值存储到了Test类的常量池中,对常量ConstClass.HELLOWORLD的引用实际                //都被转化为Test类对自身常量池的引用了。
		//这两个累在编译成Class后就不存在任何联系了。
		System.out.println(ConstClass.HELLOWORLD);
	}
}

 

 

  • 大小: 23.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics