為什麼要使用類加載器?
Java語言裡,類加載都是在程序運行期間完成的,這種策略雖然會令類加載時稍微增加一些性能開銷,但是會給java應用程序提供高度的靈活性。例如:
1.編寫一個面向接口的應用程序,可能等到運行時再指定其實現的子類;
2.用戶可以自定義一個類加載器,讓程序在運行時從網絡或其他地方加載一個二進制流作為程序代碼的一部分;(這個是Android插件化,動態安裝更新apk的基礎)
為什麼研究類加載全過程?
類加載機制
JVM把class文件加載到內存,並對數據進行校驗、解析和初始化,最終形成JVM可以直接使用的java類型的全過程。
載入
將class文件字節碼內容加載到內存中,並將這些靜態數據轉換成方法區中的運行時數據結構,在堆中生成一個代表這個類的java.lang.Class對象,作為方法區類數據的訪問入口,這個過程需要類加載器參與。
鏈接
將java類的二進制代碼合併到JVM的運行狀態之中的過程
初始化
<clinit>()方法的過程。類構造器<clinit>()方法是由編譯器自動收藏類中的所有類變量的賦值動作和靜態語句塊(static塊)中的語句合併產生<clinit>()方法在多線程環境中被正確加鎖和同步例1:
public class Demo01 { public static void main(String[] args) { A a = new A(); System.out.println(a.width); }}class A{ public static int width=100; //靜態變量,靜態域field static{ System.out.println("靜態初始化類A"); width = 300 ; } public A() { System.out.println("創建A類的對象"); }}分析:
說明:
內存中存在棧、堆(放創建好的對象)、方法區(實際也是一種特殊堆)
1、JVM加載Demo01時候,首先在方法區中形成Demo01類對應靜態數據(類變量、類方法、代碼…),同時在堆裡面也會形成java.lang.Class對象(反射對象),代表Demo01類,通過對象可以訪問到類二進制結構。然後加載變量A類信息,同時也會在堆裡面形成a對象,代表A類。
2、main方法執行時會在棧裡面形成main方法棧幀,一個方法對應一個棧幀。如果main方法調用了別的方法,會在棧裡面挨個往裡壓,main方法裡面有個局部變量A類型的a,一開始a值為null,通過new調用類A的構造器,棧裡面生成A()方法同時堆裡面生成A對象,然後把A對像地址付給棧中的a,此時a擁有A對像地址。
3、當調用A.width時,調用方法區數據。
當類被引用的加載,類只會加載一次
類的主動引用(一定會發生類的初始化)
java.lang.reflect包的方法對類進行反射調用類的被動引用(不會發生類的初始化)
例2:
public class Demo01 { static{ System.out.println("靜態初始化Demo01"); } public static void main(String[] args) throws Exception { System.out.println("Demo01的main方法!"); System.out.println(System.getProperty("java.class.path")); //主動引用// new A();// System.out.println(A.width);// Class.forName("com.sinosoft.test.A"); //被動引用// System.out.println(A.MAX);// A[] as = new A[10]; System.out.println(B.width);//B類不會被加載}}class B extends A { static { System.out.println("靜態初始化B"); }}class A extends A_Father { public static int width=100; //靜態變量,靜態域field public static final int MAX=100; static { System.out.println("靜態初始化類A"); width=300; } public A(){ System.out.println("創建A類的對象"); }}class A_Father extends Object { static { System.out.println("靜態初始化A_Father"); }}總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。