Java類初始化執行流程解析
測試代碼:
package com.test.ClassLaoderTest; public class test1 { public static String s_variable = "靜態變量"; public String init_variable = "公開的變量"; private String p_variable = "私有的變量"; //靜態代碼塊 static { System.out.println(s_variable); System.out.println("靜態代碼塊初始化執行瞭"); } //初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("初始化代碼塊執行淪"); } //構造方法 public test1(){ System.out.println("我是構造方法"); } public static void main(String[] args) { } }
直接運行:
main方法裡面不做任何調用的情況下,自動調用的是靜態代碼塊和靜態變量
(2)調用靜態變量和靜態方法:
測試代碼:
package com.test.ClassLaoderTest; public class test1 { public static String s_variable = "靜態變量"; public String init_variable = "公開的變量"; private String p_variable = "私有的變量"; //靜態代碼塊 static { System.out.println(s_variable); System.out.println("靜態代碼塊初始化執行瞭"); } //初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("初始化代碼塊執行淪"); } //構造方法 public test1(){ System.out.println("我是構造方法"); } //靜態方法 public static void test1(){ System.out.println("這是靜態方法"); } public static void main(String[] args) { System.out.println(test1.s_variable); test1.test1(); } }
運行:
結論:當我調用靜態方法/靜態變量時,隻會傢在靜態代碼塊,其餘的代碼塊/構造方法不會被加載
(3)創建對象:
package com.test.ClassLaoderTest; public class test1 { public static String s_variable = "靜態變量"; public String init_variable = "公開的變量"; private String p_variable = "私有的變量"; //靜態代碼塊 static { System.out.println(s_variable); System.out.println("靜態代碼塊初始化執行瞭"); } //初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("初始化代碼塊執行瞭"); } //構造方法 public test1(){ System.out.println("我是構造方法"); } //靜態方法 public static void test1(){ System.out.println("這是靜態方法"); } public static void main(String[] args) { test1 t1 = new test1(); } }
運行結果:
輸出內容:
靜態變量
靜態代碼塊初始化執行瞭
公開的變量
私有的變量
初始化代碼塊執行瞭
我是構造方法
結論:當創建對象/實例化的時候,調用順序:靜態代碼塊->初始化代碼->構造方法,最後執行的才是構造方法
(4)有繼承關系下的類初始化執行流程:
環境:
父類:
package com.test.ClassLaoderTest; public class father { public static String s_variable = "父類靜態變量"; public String init_variable = "父類公開的變量"; private String p_variable = "父類私有的變量"; //父類靜態代碼塊 static { System.out.println(s_variable); System.out.println("父類靜態代碼塊初始化執行瞭"); } //父類初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("父類初始化代碼塊執行瞭"); } //構造方法 public father(){ System.out.println("我是父類構造方法"); } //父類靜態方法 public static void test1(){ System.out.println("這是父類靜態方法"); } }
test1.java:
繼承其父類father:
package com.test.ClassLaoderTest; public class test1 extends father{ public static String s_variable = "子類靜態變量"; public String init_variable = "子類公開的變量"; private String p_variable = "子類私有的變量"; //子類靜態代碼塊 static { System.out.println(s_variable); System.out.println("子類靜態代碼塊初始化執行瞭"); } //子類初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("子類初始化代碼塊執行瞭"); } //子類構造方法 public test1(){ System.out.println("我是子類構造方法"); } //子類靜態方法 public static void test1(){ System.out.println("這是子類靜態方法"); } public static void main(String[] args) { } }
main方法不做任何操作,運行:
隻要extends繼承瞭,優先調用父類靜態代碼塊
(5)有繼承關系下的調用靜態方法:
修改子類即可:
package com.test.ClassLaoderTest; public class test1 extends father{ public static String s_variable = "子類靜態變量"; public String init_variable = "子類公開的變量"; private String p_variable = "子類私有的變量"; //子類靜態代碼塊 static { System.out.println(s_variable); System.out.println("子類靜態代碼塊初始化執行瞭"); } //子類初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("子類初始化代碼塊執行瞭"); } //子類構造方法 public test1(){ System.out.println("我是子類構造方法"); } //子類靜態方法 public static void test1(){ System.out.println("這是子類靜態方法"); } public static void main(String[] args) { test1.test1(); father.test1(); } }
運行:
結果:
父類靜態變量
父類靜態代碼塊初始化執行瞭
子類靜態變量
子類靜態代碼塊初始化執行瞭
這是子類靜態方法
這是父類靜態方法
main方法中,誰優先調用靜態方法,就優先加載誰
(6)有繼承關系下的創建對象:
代碼:
package com.test.ClassLaoderTest; public class test1 extends father{ public static String s_variable = "子類靜態變量"; public String init_variable = "子類公開的變量"; private String p_variable = "子類私有的變量"; //子類靜態代碼塊 static { System.out.println(s_variable); System.out.println("子類靜態代碼塊初始化執行瞭"); } //子類初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("子類初始化代碼塊執行瞭"); } //子類構造方法 public test1(){ System.out.println("我是子類構造方法"); } //子類靜態方法 public static void test1(){ System.out.println("這是子類靜態方法"); } public static void main(String[] args) { test1 t1 =new test1(); } }
運行:
結果:
父類靜態變量
父類靜態代碼塊初始化執行瞭
子類靜態變量
子類靜態代碼塊初始化執行瞭
父類公開的變量
父類私有的變量
父類初始化代碼塊執行瞭
我是父類構造方法
子類公開的變量
子類私有的變量
子類初始化代碼塊執行瞭
我是子類構造方法
結論:通過結果會發現,不管是子類還是父類靜態代碼塊,靜態代碼塊在哪裡都是爸爸級別,最先加載的,當創建test1對象的時候,優先加載的是父類代碼塊,那麼他的初始化執行流程如下:父類靜態代碼塊>子類靜態代碼塊>父類初始化代碼塊>父類構造方法>子類代碼塊>子類構造方法
(7) 有繼承關系下的創建父類對象:
package com.test.ClassLaoderTest; public class test1 extends father{ public static String s_variable = "子類靜態變量"; public String init_variable = "子類公開的變量"; private String p_variable = "子類私有的變量"; //子類靜態代碼塊 static { System.out.println(s_variable); System.out.println("子類靜態代碼塊初始化執行瞭"); } //子類初始化代碼塊 { System.out.println(init_variable); System.out.println(p_variable); System.out.println("子類初始化代碼塊執行瞭"); } //子類構造方法 public test1(){ System.out.println("我是子類構造方法"); } //子類靜態方法 public static void test1(){ System.out.println("這是子類靜態方法"); } public static void main(String[] args) { father father = new father(); } }
運行:
結果:
父類靜態變量
父類靜態代碼塊初始化執行瞭
子類靜態變量
子類靜態代碼塊初始化執行瞭
父類公開的變量
父類私有的變量
父類初始化代碼塊執行瞭
我是父類構造方法
結論:優先執行的是兩個類的靜態代碼塊,然後是父類型的代碼塊和構造方法,而子類的代碼塊和構造方法沒有被執行是因為沒有實例化子類,所以肯定是沒有他的,那麼隻有在創建對象的時候,才會調用代碼塊和構造方法
到此這篇關於Java類初始化執行流程的文章就介紹到這瞭,更多相關Java類初始化執行流程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!