这篇文章给大家分享的是有关Java类初始化时机测试方法是什么的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。
<clinit>()方法
Java 类加载的初始化过程中,编译器按语句在源文件中出现的顺序,依次自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并产生方法。 如果类中没有静态语句和静态代码块,那可以不生成<clinit>() 方法。
并且 <clinit>() 不需要显式调用父类(接口除外,接口不需要调用父接口的初始化方法,只有使用到父接口中的静态变量时才需要调用)的初始化方法 <clinit>(),虚拟机会保证在子类的 <clinit>() 方法执行之前,父类的 <clinit>() 方法已经执行完毕(所以java.lang.Object 类总是第一个被加载)
准备父类和子类
class Father { static int father_a = 1; static { System.out.println("父类静态代码块执行"); } static class StaticInnerClass { static { System.out.println("静态内部类静态代码块执行"); } } } class Son extends Father { static { System.out.println("子类静态代码块执行"); son_a = 300; } static int son_a = 100; static final int M = 1; }
Main方法:
1:父类没有被引用但是会被先加载
new Son();
2:反射也会产生主动引用:
Class a = Class.forName("clinit.Son");
(运行结果同1)
3:子类使用父类静态变量或方法不会产生类的引用
System.out.println("Father.a = " + Son.father_a);
4:通过类创建数组不会加载类(只是开辟一块空间)
Son[] sons = new Son[8];
5:使用常量不会加载父类和之类(常量在Linking阶段就保存在常量池当中了)
System.out.println("Son.CONST = " + Son.CONST);
6:引用静态内部类不会加载外部类(应用于单例模式)
new Father.StaticInnerClass();
代码总结:
public static void main(String[] args) throws Exception { // 1.父类没有被引用但是会被先加载 // new Son(); // 2.反射会产生主动引用 // Class a = Class.forName("clinit.Son"); // 3.子类使用父类静态变量或方法不会产生类的引用 // System.out.println("Father.a = " + Son.father_a); // 4.通过类创建数组不会加载类(只是开辟一块空间) // Son[] sons = new Son[8]; // 5.使用常量不会加载父类和之类(常量在Linking阶段就保存在常量池当中了) // System.out.println("Son.CONST = " + Son.CONST); // 6.引用静态内部类不会加载外部类(应用于单例模式) // new Son.StaticInnerClass(); } }
PS:由于是按出现的顺序执行的,为了避免不必要的麻烦,应尽量把静态变量写在静态代码块之前
public class Test { public static void main(String[] args) { System.out.println("a = " + cls.a); } } class cls { static int a = 10;8 static { a = 20; }9 }
如果 调换顺序输出结果将是 a = 10
class cls { static { a = 20; } static int a = 10; }
感谢各位的阅读!关于Java类初始化时机测试方法是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。