class Nolization{
static{
System.out.println("Nolization init");
}
public static int value = 123;
}
class Contant extends Nolization{
static{
System.out.println("Contant init");
}
}
public class ContantClass {
public static void main(String[] args) {
System.out.println(Contant.value);
}
}
上面这段代码的执行结果是 Nolization init
123
并没有输出 Contant init,这是因为 jvm 对于 静态字段,只有直接定义这个字段的类才会被初始化。
再看下面这段代码
class Nolization{
static{
System.out.println("Nolization init");
}
public static final int value = 123;
}
class Contant extends Nolization{
static{
System.out.println("Contant init");
}
}
public class ContantClass {
public static void main(String[] args) {
System.out.println(Contant.value);
}
}
相比于上段代码,仅仅是将value 从public static int 改为 public static final int ,输出的结果变成了 123,不再输出任何类的初始化信息。
这是因为 jvm 在编译阶段 将常量 123 存储到了 ContantClass 的常量池中,对 Contant.value 的引用实际都转化为 ContantClass 对自身常量的引用了,也就是说 ContantClass 的class文件中并不存在 Nolization 的任何调用入口,在编译成class文件之后,这两个字节码文件已经不存在任何联系了。