詳解Java中類的加載與其初始化
java內存分析
類加載的過程
類的加載與ClassLoader的理解
類的初始化
package Collections; public class text1 { public static void main(String[]args){ A a=new A(); System.out.println(A.m); } } class A{ static { System.out.println("A類靜態(tài)代碼塊初始化"); m=300; } static int m=100; public A(){ System.out.println("A類的無參構造初始化"); } }
輸出:
A類靜態(tài)代碼塊初始化
A類的無參構造初始化
100
為什么最終輸出的m值為100呢?
分析如下:
首先類進行加載和鏈接,如下所示:
注:在鏈接階段的準備工作時,編譯器會為類變量賦默認值為0,即此時的m為0
鏈接完畢后進行類的初始化,這一過程將會執(zhí)行類構造器()方法,將類中所有類變量的賦值語句以及靜態(tài)代碼塊中的語句收集和合并:
<clinit>() { System.out.println("A類靜態(tài)代碼塊初始化"); m=300; m=100; }
第二條m的賦值語句,覆蓋了第一條的300,因此最終輸出為100
會發(fā)生類的初始化的場景
類的主動引用(一定會發(fā)生類的初始化)
類的主動引用
package Collections; import static Collections.Son.m; public class text1 { static { System.out.println("Main類被加載"); } public static void main(String[]args) throws ClassNotFoundException { Son son=new Son(); } } class Father{ static int a=10; static{ System.out.println("Father類被加載"); } } class Son extends Father{ static { System.out.println("子類被加載"); m= 300; } static int m =100; static final int M = 1; }
輸出:
Main類被加載
Father類被加載
子類被加載
反射也會產生主動引用
package Collections; import static Collections.Son.m; ???????public class text1 { static { System.out.println("Main類被加載"); } public static void main(String[]args) throws ClassNotFoundException { Class.forName("Collections.Son"); } } class Father{ static int a=10; static{ System.out.println("Father類被加載"); } } class Son extends Father{ static { System.out.println("子類被加載"); m= 300; } static int m =100; static final int M = 1; }
輸出:
Main類被加載
Father類被加載
子類被加載
類的被動引用(不會發(fā)生類的初始化)
當訪問一個靜態(tài)域時,只有真正聲明這個域的類才會被初始化,如:當通過子類引用父類的靜態(tài)變量,不會導致子類初始化。
舉例:
package Collections; import static Collections.Son.m; ???????public class text1 { static { System.out.println("Main類被加載"); } public static void main(String[]args) throws ClassNotFoundException { System.out.println(Son.a); } } class Father{ static int a=10; static{ System.out.println("Father類被加載"); } } class Son extends Father{ static { System.out.println("子類被加載"); m= 300; } static int m =100; static final int M = 1; }
輸出:
Main類被加載
Father類被加載
10
通過數組定義類引用,不會觸發(fā)此類的初始化
舉例:
package Collections; import static Collections.Son.m; ???????public class text1 { static { System.out.println("Main類被加載"); } public static void main(String[]args) throws ClassNotFoundException { Son[] arry=new Son[5]; } } class Father{ static int a=10; static{ System.out.println("Father類被加載"); } } class Son extends Father{ static { System.out.println("子類被加載"); m= 300; } static int m =100; static final int M = 1; }
輸出:
Main類被加載
引用常量不會觸發(fā)此類的初始化(常量在鏈接階段就存入調用類的常量池中了)
舉例:
package Collections; import static Collections.Son.m; ???????public class text1 { static { System.out.println("Main類被加載"); } public static void main(String[]args) throws ClassNotFoundException { System.out.println(Son.M); } } class Father{ static int a=10; static{ System.out.println("Father類被加載"); } } class Son extends Father{ static { System.out.println("子類被加載"); m= 300; } static int m =100; static final int M = 1; }
輸出:
Main類被加載
???????1
以上就是詳解Java中類的加載與其初始化的詳細內容,更多關于Java類加載與初始化的資料請關注腳本之家其它相關文章!
相關文章
Java 實戰(zhàn)項目錘煉之嘟嘟健身房管理系統(tǒng)的實現(xiàn)流程
讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實現(xiàn)一個健身房管理系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11Java中的CopyOnWriteArrayList你了解嗎
CopyOnWriteArrayList是Java集合框架中的一種線程安全的List實現(xiàn),這篇文章主要來和大家聊聊CopyOnWriteArrayList的簡單使用,需要的可以參考一下2023-06-06java格式化數字操作 NumberFormat及DecimalFormat
這篇文章主要介紹了java格式化數字操作 NumberFormat及DecimalFormat,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java工作環(huán)境的配置與Eclipse的安裝過程
這篇文章主要介紹了Java工作環(huán)境的配置與Eclipse的安裝過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02Spring Cloud Alibaba之Sentinel實現(xiàn)熔斷限流功能
這篇文章主要介紹了Spring Cloud Alibaba之Sentinel,這里使用阿里的sentinel來實現(xiàn)熔斷限流功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04