虚拟机加载机制
代码清单7-1
public class Six { static { System.out.println("SuperClass init!"); } public static int value = 123; } public class Seven extends Six{ static { System.out.println("SubClass init!"); } public static String name = "Alibaba"; } /** * 通过子类引用父类的静态字段,不会导致子类的初始化 * 对于静态字段,只有直接定义这个字段的类才会被初始化 **/ public class Eight { public static void main(String[] args) { System.out.println(Seven.value); } }
SuperClass init! 123
修改一下,在初始化子类时,如果父类还没有进行初始化,则需要先出发其父类的初始化。
/** * 通过子类引用父类的静态字段,不会导致子类的初始化 * 被动使用字段的情况 * 对于静态字段,只有直接定义这个字段的类才会被初始化 **/ public class Eight { public static void main(String[] args) { System.out.println(Seven.name); } }
SuperClass init! SubClass init! Alibaba
情况二
/** * 被动使用字段的情况 * 通过数组定义来引用类,不会触发此类初始化 **/ public class Eight { public static void main(String[] args) { Six[] sca = new Six[10]; } }
控制台什么信息都没有输出,但是如果使用new关键字实例化类Six的对象时,会发生主动引用。
public class Eight { public static void main(String[] args) { Six[] sca = new Six[10]; for(int i=0; i< sca.length; i++){ sca[i] = new Six(); //使用new关键字创建 } } }
SuperClass init!
情况三
public class Six { static { System.out.println("ConstClass init!"); } public static final String HelloWorld = "hello world"; } /** * 被动使用类字段 final修饰的 * 常量在编译阶段会存到该调用类的常量池中,本质上没有直接引用到定义常量的类, * 故不会触发定义常量的类的初始化 **/ public class Seven{ public static void main(String[] args) { System.out.println(Six.HelloWorld); } }
hello world
把HelloWorld前的final修饰符去掉后
public class Six { static { System.out.println("ConstClass init!"); } public static String HelloWorld = "hello world"; } /** * 被动使用类字段 final修饰的 * 常量在编译阶段会存到该调用类的常量池中,本质上没有直接引用到定义常量的类, * 故不会触发定义常量的类的初始化 **/ public class Seven{ public static void main(String[] args) { System.out.println(Six.HelloWorld); } }
ConstClass init! hello world
去掉final后,就能出发父类Six的初始化了。
作者:Ryanjie
出处:http://www.cnblogs.com/ryanjan/
本文版权归作者和博客园所有,欢迎转载。转载请在留言板处留言给我,且在文章标明原文链接,谢谢!
如果您觉得本篇博文对您有所收获,觉得我还算用心,请点击右下角的 [推荐],谢谢!