被动引用
最近读了深入理解Java虚拟机这本书,在学习类加载机制的时候,突然反应过来,一些笔试题经常考的,子类继承了父类且子类和父类的构造器中均有打印输出,让作答输出了哪些内容,其实考的知识点就是类加载的时机。
被动引用的例子之三
package com.depthmind.classloader;
/**
* 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,
* 因此不会触发定义常量的类的初始化
*/
public class ConstClass {
static {
System.out.println("ConstClass init");
}
public static final String HelloWord = "hello word";
}
package com.depthmind.classloader.test;
import com.depthmind.classloader.ConstClass;
import org.junit.Test;
public class TestConstClass {
@Test
public void notInitialization() {
System.out.println(ConstClass.HelloWord);
}
}
作者原话,上述代码运行之后没有输出“ConstClass init!“,是因为虽然在Java源码中引用了ConstaClass类中的常量HelloWord,但其实在编译阶段通过常量传播优化,已经将此常量值的“hello word“存储到了TestConstClass类的常量池中,以后TestConstClass对常量ConstClass.HelloWord的引用实际都被转化为了TestConstClass对自身常量池的引用了。也就是说实际上TestConstClass的class文件之中并没有ConstClass类的符号引用入口类,这两个类在编译成class文件之后就不存在任何联系了。