爲何研究類加載全過程?java
類加載機制數組
例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類的對象"); } }
分析:數據結構
說明:多線程
內存中存在棧、堆(放建立好的對象)、方法區(實際也是一種特殊堆)spa
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對象地址。code
3、當調用A.width時,調用方法區數據。對象
當類被引用的加載,類只會加載一次blog
例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"); } }