JVM類加載機(jī)制
目錄:

JVM加載的過程
加載
為什么需要加載?
加載什么?
怎么加載?
JVM加載類的工具
系統(tǒng)自帶工具
Bootstrap,根加載器(C++),程序員不可見
擴(kuò)展類加載器(java),程序員可見
系統(tǒng)加載器(Java),程序員可見
用戶自定義工具
加載的結(jié)果是什么?
連接
驗證『萬一要是用戶自己寫的加載器加載的.class文件不符合JVM規(guī)范怎么辦?--驗證之』
準(zhǔn)備『給類的靜態(tài)變量分配內(nèi)存,并且設(shè)置默認(rèn)值』/補(bǔ)充這邊是和變異期常量有關(guān)系嗎?
解析
初始化『JVM遇到6種情況的時候,就會初始化類,把用戶給的值賦值給對應(yīng)的變量』
為什么需要加載?--java程序經(jīng)過編譯成. class文件,再裝在到內(nèi)存里面(由classloader執(zhí)行),這樣才能執(zhí)行java程序
| 演示程序123456789101112131415161718 | package classloader;public class Singleton {//這邊的內(nèi)存圖是怎么畫的?自己里面創(chuàng)建自己是怎么回事?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 文件從硬盤到內(nèi)存的遷移


也就是在堆區(qū)域創(chuàng)建一個Class類的對象『類的名稱是Class』
Class對象是JVM在加載對應(yīng)的類文件到方法區(qū)之后,在堆區(qū)生成一個與該類文件對應(yīng)的Class對象。強(qiáng)調(diào):不管這個類生成多少個對象,獄該類對應(yīng)的Class對象只有一個
Class對象可以封裝類在『方法區(qū)』內(nèi)的數(shù)據(jù)結(jié)構(gòu):類里面的內(nèi)容,都可以通過Class對象獲得,像鏡子一樣,是整個反射的入口,可以看到目標(biāo)類的關(guān)聯(lián)的class結(jié)構(gòu),通過Class對象可以訪問目標(biāo)類的字段和方法
怎么加載?
加載方式




加載的工具

根類加載器C++,系統(tǒng)類加載器和擴(kuò)展列加載器是java
Classloader類,將二進(jìn)制名稱轉(zhuǎn)換成文件名,然后嘗試著從文件系統(tǒng)讀取該名稱的.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標(biāo)明是由根加載器Bootstrap加載的,由C++編寫Class class1=Class.forName("classloader.Singleton");System.out.println(class1.getClassLoader());//輸出sun.misc.Launcher$AppClassLoader@105d88a}} |
加載的結(jié)果



連接:
即本來用javac進(jìn)行編譯,但是有些人自己編譯,生成的字節(jié)碼文件不符合jvm對字節(jié)碼文件的規(guī)范,因此需要檢測
強(qiáng)調(diào)靜態(tài)變量(static):此時對象還不存在,此時還不涉及實例方法。靜態(tài)變量不屬于某一個對象,是屬于一個類的,所有的該類的對象都可以調(diào)用該靜態(tài)變量。因此在該類加載到內(nèi)存的時候,就可以給給靜態(tài)變量分配內(nèi)存了,并且初始化為默認(rèn)值 boolean類型:false,int 類型:0等
【感覺像是一個屋子在規(guī)劃的時候,就要劃分好公共空間,之后要是有具體的別人住進(jìn)來之后,可以根據(jù)不同人的不同的需求在各自的地方進(jìn)行活動,但是公用的部分一定是在建設(shè)一始就劃分好的,比如小區(qū)的公園和衛(wèi)生間,并且要公園里面的花花草草給弄好,不能說就建了一個花園的大概的外圍,里面什么都不搞,連地都不松一下土,這不行,還有比如衛(wèi)生間,也是要把里面的設(shè)備搞齊全了,沖水的設(shè)備,紙簍都要放好,不能等業(yè)主進(jìn)來了使用的時候才發(fā)現(xiàn),“我擦,怎么什么都只是空樣子”!至于后來小區(qū)業(yè)主進(jìn)來了,可以在自己家里面再搞其他的花草什么的別人也管不了,】
解析:之后再說 /2015.04.29補(bǔ)充:這邊的解析 是將符號飲用轉(zhuǎn)換為直接引用,是多態(tài)中后期綁定的內(nèi)容嗎?
初始化:這個不和『連接』里面的『準(zhǔn)備』重復(fù)嗎?
不重復(fù)
因為此時是把用戶想賦的值賦值給靜態(tài)變量
舉例:
| 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方法的類
新聞熱點(diǎn)
疑難解答