JVM類加載機制
目錄:
JVM加載的過程
加載
為什么需要加載?
加載什么?
怎么加載?
JVM加載類的工具
系統自帶工具
Bootstrap,根加載器(C++),程序員不可見
擴展類加載器(java),程序員可見
系統加載器(Java),程序員可見
用戶自定義工具
加載的結果是什么?
連接
驗證『萬一要是用戶自己寫的加載器加載的.class文件不符合JVM規范怎么辦?--驗證之』
準備『給類的靜態變量分配內存,并且設置默認值』/補充這邊是和變異期常量有關系嗎?
解析
初始化『JVM遇到6種情況的時候,就會初始化類,把用戶給的值賦值給對應的變量』
為什么需要加載?--java程序經過編譯成. class文件,再裝在到內存里面(由classloader執行),這樣才能執行java程序
演示程序123456789101112131415161718 | package classloader; public class Singleton {
//這邊的內存圖是怎么畫的?自己里面創建自己是怎么回事?
PRivate static Singleton singleton= new Singleton();
public static int counter1;
public static int counter2= 0 ;
private Singleton(){
counter1++;
counter2++;
}
public static Singleton getInstance(){
return singleton;
}
} |
12345678910 | package classloader; public class MyClass { public static void main(String[] args) {
Singleton singleton=Singleton.getInstance();
System.out.println( "counter1-" +singleton.counter1);
System.out.println( "counter2-" +singleton.counter2); }
} |
AWT,聊天程序中可以使用該方法
加載
加載什么?--class 文件從硬盤到內存的遷移
也就是在堆區域創建一個Class類的對象『類的名稱是Class』
Class對象是JVM在加載對應的類文件到方法區之后,在堆區生成一個與該類文件對應的Class對象。強調:不管這個類生成多少個對象,獄該類對應的Class對象只有一個
Class對象可以封裝類在『方法區』內的數據結構:類里面的內容,都可以通過Class對象獲得,像鏡子一樣,是整個反射的入口,可以看到目標類的關聯的class結構,通過Class對象可以訪問目標類的字段和方法
怎么加載?
加載方式
加載的工具
根類加載器C++,系統類加載器和擴展列加載器是java
Classloader類,將二進制名稱轉換成文件名,然后嘗試著從文件系統讀取該名稱的.class文件
123456789101112131415 | package classloader;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
Class clazz=Class.forName( "java.lang.String" );
System.out.println(clazz.getClassLoader()); //輸出null
//獲得String類的加載方式,null標明是由根加載器Bootstrap加載的,由C++編寫
Class class1=Class.forName( "classloader.Singleton" );
System.out.println(class1.getClassLoader()); //輸出sun.misc.Launcher$AppClassLoader@105d88a
} } |
加載的結果
連接:
即本來用javac進行編譯,但是有些人自己編譯,生成的字節碼文件不符合jvm對字節碼文件的規范,因此需要檢測
強調靜態變量(static):此時對象還不存在,此時還不涉及實例方法。靜態變量不屬于某一個對象,是屬于一個類的,所有的該類的對象都可以調用該靜態變量。因此在該類加載到內存的時候,就可以給給靜態變量分配內存了,并且初始化為默認值 boolean類型:false,int 類型:0等
【感覺像是一個屋子在規劃的時候,就要劃分好公共空間,之后要是有具體的別人住進來之后,可以根據不同人的不同的需求在各自的地方進行活動,但是公用的部分一定是在建設一始就劃分好的,比如小區的公園和衛生間,并且要公園里面的花花草草給弄好,不能說就建了一個花園的大概的外圍,里面什么都不搞,連地都不松一下土,這不行,還有比如衛生間,也是要把里面的設備搞齊全了,沖水的設備,紙簍都要放好,不能等業主進來了使用的時候才發現,“我擦,怎么什么都只是空樣子”!至于后來小區業主進來了,可以在自己家里面再搞其他的花草什么的別人也管不了,】
解析:之后再說 /2015.04.29補充:這邊的解析 是將符號飲用轉換為直接引用,是多態中后期綁定的內容嗎?
初始化:這個不和『連接』里面的『準備』重復嗎?
不重復
因為此時是把用戶想賦的值賦值給靜態變量
舉例:
1234 | public class Test{
private static int i= 3 ; } |
12345678 | public class Test{
private static int i;
static
{
i= 3 ;
} } |
new Test();
int b=Tetst.a;或者 Test.a=b;
Class.forName("classloader.Test");
12345678 | class Father {} class Child extends Father {
public static int i; } Child.a= 3 ; |
啟動類:含有main方法的類
新聞熱點
疑難解答