java中类加载机制、类加载过程和类加载器层次
1.類加載機(jī)制
jvm把class文件加載到內(nèi)存,并對數(shù)據(jù)進(jìn)行校驗(yàn)、解析和初始化,最終形成jvm可以直接使用的java類型的過程。
(1)加載
將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)中的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),在堆中生成一個(gè)代表這個(gè)類的java.lang.Class對象,作為方法區(qū)類數(shù)據(jù)的訪問入口。
(2)鏈接 將java類的二進(jìn)制代碼合并到j(luò)vm的運(yùn)行狀態(tài)之中的過程
2.1 驗(yàn)證確保加載的類信息符合jvm規(guī)范,沒有安全方面的問題。2.2 準(zhǔn)備 正式為類變量(static變量)分配內(nèi)存并設(shè)置類變量初始值的階段,這些內(nèi)存都將在方法區(qū)中進(jìn)行分配。2.3 解析虛擬機(jī)常量池內(nèi)的符號引用替換為直接引用的過程。(比如String s ="aaa",轉(zhuǎn)化為 s的地址指向“aaa”的地址)(3)初始化
初始化階段是執(zhí)行類構(gòu)造器方法的過程。類構(gòu)造器方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態(tài)語句塊(static塊)中的語句合并產(chǎn)生的。
當(dāng)初始化一個(gè)類的時(shí)候,如果發(fā)現(xiàn)其父類還沒有進(jìn)行過初始化,則需要先初始化其父類的初始化
虛擬機(jī)會保證一個(gè)類的構(gòu)造器方法在多線程環(huán)境中被正確加鎖和同步
當(dāng)訪問一個(gè)java類的靜態(tài)域時(shí),只有真正聲明這個(gè)靜態(tài)變量的類才會被初始化。
2.類加載過程
類加載過程分為:類的主動引用和類的被動引用
類的主動引用(一定會發(fā)生類的初始化)
--new一個(gè)類的對象--調(diào)用類的靜態(tài)成員(除了final常量)和靜態(tài)方法--使用java.lang.reflect包的方法對類進(jìn)行反射調(diào)用--當(dāng)初始化一個(gè)類,如果其父類沒有被初始化,則先初始化他的父類--當(dāng)要執(zhí)行某個(gè)程序時(shí),一定先啟動main方法所在的類類的被動引用(不會發(fā)生類的初始化)
--當(dāng)訪問一個(gè)靜態(tài)變量時(shí),只有真正生命這個(gè)靜態(tài)變量的類才會被初始化(通過子類引用父類的靜態(tài)變量,不會導(dǎo)致子類初始化)--通過數(shù)組定義類應(yīng)用,不會觸發(fā)此類的初始化 A[] a = new A[10];--引用常量(final類型)不會觸發(fā)此類的初始化(常量在編譯階段就存入調(diào)用類的常量池中了)3.類加載器的層次結(jié)構(gòu)(樹狀結(jié)構(gòu))
引導(dǎo)類加載器(bootstrap class loader)c語言編寫
--他用類加載java 的核心庫(String 、Integer、List。。。)在jre/lib/rt.jar路徑下的內(nèi)容,是用C代碼來實(shí)現(xiàn)的,并不繼承自java.lang.ClassLoader。--加載擴(kuò)展類和應(yīng)用程序類加載器。并指定他們的父類加載器。擴(kuò)展類加載器(extensions class loader)
--用來加載java的擴(kuò)展庫(jre/ext/*.jar路徑下的內(nèi)容)java虛擬機(jī)的實(shí)現(xiàn)會自動提供一個(gè)擴(kuò)展目錄。該類加載器在此目錄里面查找并加載java類。應(yīng)用程序類加載器(application class loader)--他根據(jù)java應(yīng)用的類路徑(classpath路徑),一般來說,java應(yīng)用的類都是由他來完成加載的自定義類加載器
--開發(fā)人員可以通過繼承java.lang.ClassLoader類的方式實(shí)現(xiàn)自己的類加載器,以滿足一些特殊的需求。擴(kuò)展類加載器、應(yīng)用程序類加載器、自定義類加載器均是由java實(shí)現(xiàn),都繼承java.lang.ClassLoader類。
類加載器的代理模式:雙親委托機(jī)制
--就是某個(gè)特定的類加載器在接收到加載類的請求后,首先將加載任務(wù)委托給父類加載器,一次追溯,直到最高的爺爺輩的,如果父類加載器可以完成類加載任務(wù),就成功返回;只要父類加載器無法完成次加載任務(wù)時(shí),才自己加載。--雙親機(jī)制是為了保證java核心庫的類型安全,不會出現(xiàn)用戶自己能定義java.lang.Object類的情況。雙親委托機(jī)制是代理模式的一種,并不是所有的類加載器都采用雙親委托機(jī)制,tomcat服務(wù)器類加載器也使用代理模式,所不同的是他是首先嘗試自己去加載某個(gè)類,如果找不到在代理給父類加載器。
轉(zhuǎn)載地址:http://www.cnblogs.com/pengfeiliu/p/4420793.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的java中类加载机制、类加载过程和类加载器层次的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 类中各成分加载顺序和内存中的存
- 下一篇: Oracle三种循环:for,while