类加载顺序
package com.ai.common; public class StaticInit { private static class StaticPa{ static final int high2 =13; final int high3 = print("Init StaticPa variable high3"); static { System.out.println("StaticPa static block: "+high2); } private StaticPa(int a){ System.out.println("StaticPa constructor: "+a); } public static int print(String str){ System.out.println(str); return 0; } } private static class StaticTest extends StaticPa{ static final int final1 = 123; static final double final2 = 234d; static final String final3 = "222"; static final String final4 = new String("final4"); final int high4 = print("Init StaticTest variable high4"); static { System.out.println("StaticTest static block: "+final4); } public static void test(){ System.out.println("static method"); } private StaticTest(int a){ super(a); System.out.println("StaticTest constructor: "+a); } } public static void main(String[] args) { System.out.println("Before StaticTest.final1"); Object temp = StaticTest.final1; System.out.println("After StaticTest.final1"); System.out.println(); System.out.println("Before StaticTest.final2"); temp = StaticTest.final2; System.out.println("After StaticTest.final2"); System.out.println(); System.out.println("Before StaticTest.final3"); temp = StaticTest.final3; System.out.println("After StaticTest.final3"); System.out.println(); System.out.println("Before StaticTest.final4"); temp = StaticTest.final4; System.out.println("After StaticTest.final4"); System.out.println(); System.out.println("Before StaticTest.test()"); StaticTest.test(); System.out.println("After StaticTest.test()"); System.out.println(); System.out.println("Before StaticTest.test()"); StaticTest.test(); System.out.println("After StaticTest.test()"); System.out.println(); System.out.println("Before new StaticTest()"); StaticTest st = new StaticTest(111); System.out.println("After new StaticTest()"); } }
执行后
对于Static final的基本数据类型常量 以及 Static final的String常量调用 不会导致类初始化;
对于其它任何static Field/Method/调用都会初始化类静态Field与静态代码块, 顺序为 父类Static Field/Block(自上而下顺序加载) --> 子类Static Field/Block(自上而下顺序加载)
1 System.out.println("Before StaticTest.final1"); 2 Object temp = StaticTest.final1; 3 System.out.println("After StaticTest.final1"); 4 5 System.out.println(); 6 System.out.println("Before StaticTest.final2"); 7 temp = StaticTest.final2; 8 System.out.println("After StaticTest.final2"); 9 10 System.out.println(); 11 System.out.println("Before StaticTest.final3"); 12 temp = StaticTest.final3; 13 System.out.println("After StaticTest.final3"); 14 15 System.out.println(); 16 System.out.println("Before StaticTest.final4"); 17 temp = StaticTest.final4; 18 System.out.println("After StaticTest.final4"); 19 20 Print: 21 Before StaticTest.final1 22 After StaticTest.final1 23 24 Before StaticTest.final2 25 After StaticTest.final2 26 27 Before StaticTest.final3 28 After StaticTest.final3 29 30 Before StaticTest.final4 31 StaticPa static block: 13 32 StaticTest static block: final4 33 After StaticTest.final4
//调用静态method
System.out.println(); System.out.println("Before StaticTest.test()"); StaticTest.test(); System.out.println("After StaticTest.test()"); Print: Before StaticTest.test() StaticPa static block: 13 Init StaticTest variable high4 StaticTest static block: final4 static method After StaticTest.test()
调用Constructor初始化顺序为: 父类Static Field/Block --> 子类Static Field/Block --> 父类non-static Field/Block -->父类Constructor --> 子类non-static Field/Block --> 子类Constructor
//调用Constructor System.out.println(); System.out.println("Before new StaticTest()"); StaticTest st = new StaticTest(111); System.out.println("After new StaticTest()"); Print: Before new StaticTest() Init StaticPa variable high3 StaticPa constructor: 111 StaticTest constructor: 111 After new StaticTest()