編寫代碼以下:java
package com.zuoyan.classloader; class FinalTest{ public static final int x = 3; static { System.out.println("FinalTest static block!"); } } public class MyTest01 { public static void main(String[] args) { System.out.println(FinalTest.x); } }
代碼執行結果:dom
3spa
而後將FinalTest 類中的 public static final x = 3 中的final 去掉 改爲 public satic in x = 3 3d
package com.zuoyan.classloader; class FinalTest{ public static int x = 3; static { System.out.println("FinalTest static block!"); } } public class MyTest01 { public static void main(String[] args) { System.out.println(FinalTest.x); } }
執行結果以下:code
FinalTest static block!
3blog
而後再將 FinalTest 中的成員變量 public static final int x = 3 ,改爲 public static final int x = new Random().nextInt(3);ssl
package com.zuoyan.classloader; import java.util.Random; class FinalTest{ public static final int x = new Random().nextInt(3); static { System.out.println("FinalTest static block!"); } } public class MyTest01 { public static void main(String[] args) { System.out.println(FinalTest.x); } }
代碼執行結果以下:get
FinalTest static block!
1io
Demo01 的執行結果是 3 ,沒有輸出靜態代碼塊中的內容,就表明靜態代碼塊沒有被執行,也就是說類沒有被初始化,若是類被初始化了,靜態代碼塊是必定會執行的。編譯
緣由是: 自己 x 是 一個編譯期的常量,3 在編譯以後就會放在MyTest01 的常量池中,因此編譯完後,MyTest01 和 FinalTest之間就沒有任何關係了,刪除FinalTest.class 沒有任何關係
Demo02 的執行結果的緣由是 : x 不是一個成員變量,須要加載類,所需須要初始化類
Demo03 結果出現的緣由是: x 是一個成員變量,可是他的數值實在運行期才能肯定的,因此須要加載FinalTest類
代碼以下,請判斷代碼的執行結果
package com.zuoyan.classloader; class Parent{ static int a = 3; static { System.out.println("Parent static block"); } } class Child extends Parent{ static int b = 4; static { System.out.println("Child static block"); } } public class MyTest02 { static { System.out.println("MyTest9 static block"); } public static void main(String[] args) { System.out.println(Child.b); } }
代碼的執行結果以下:
MyTest9 static block
Parent static block
Child static block
4
出現這樣結果的緣由: 首先初始化 Main 方法所在類,而後這類調用了 Child類的成員變量,致使了Child類的初始化,一個類的初始化首先會初始化他的父類,而後初始化他的子類
可用經過運行時 添加JVM參數來查看類的加載
程序執行輸出的結果:
package com.zuoyan.classloader; class Parent2{ static int a = 3; static { System.out.println("Parent2 static block"); } } class Child2 extends Parent2{ static int b = 4; static { System.out.println("Child 2 static block"); } } public class MyTest03 { static{ System.out.println("MyTest03 static block "); } public static void main(String[] args) { Parent2 parent; System.out.println("-----------------"); parent = new Parent2(); System.out.println("-----------------"); System.out.println(parent.a); System.out.println("-----------------"); System.out.println(Child2.b); } }
程序執行的結果:
MyTest03 static block
-----------------
Parent2 static block
-----------------
3
-----------------
Child 2 static block
4
package com.zuoyan.classloader; class Parent3{ static int a =3; static { System.out.println("Parent3 static block"); } static void doSomething(){ System.out.println("do something"); } } class Child3 extends Parent3{ static{ System.out.println("Child3 static block"); } } public class MyTest04 { public static void main(String[] args) { System.out.println(Child3.a); Child3.doSomething(); } }
程序執行出來的結果:
Parent3 static block 3 do something
注意: a 自己是定義在父類中,我雖然經過子類來訪問父類的成員變量,可是在本質上,是對於父類的主動使用,換句話說,就是成員變量定義在哪就是對誰的主動使用 (誰擁有就是對誰的主動使用)。
package com.zuoyan.classloader; class CL{ static { System.out.println("Class CL"); } } public class MyTest05 { public static void main(String[] args) throws Exception { ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); Class<?> clazz = systemClassLoader.loadClass("com.zuoyan.classloader.MyTest05"); System.out.println(clazz); System.out.println("----------------------"); clazz = Class.forName("com.zuoyan.classloader.CL"); System.out.println(clazz); } }
執行結果:
class com.zuoyan.classloader.MyTest05 ---------------------- Class CL class com.zuoyan.classloader.CL