本篇內(nèi)容介紹了“java類加載過程分為哪些步驟”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
在上栗等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、成都網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),營(yíng)銷型網(wǎng)站建設(shè),外貿(mào)網(wǎng)站制作,上栗網(wǎng)站建設(shè)費(fèi)用合理。
它是Java將字節(jié)碼數(shù)據(jù)從不同的數(shù)據(jù)源讀取到JVM中,并映射為JVM認(rèn)可的數(shù)據(jù)結(jié)構(gòu)(Class對(duì)象)。這里的數(shù)據(jù)源可能是各種各樣的形態(tài),如jar文件、class文件,甚至是網(wǎng)絡(luò)數(shù)據(jù)源等。如果輸入數(shù)據(jù)不是ClassFile的結(jié)構(gòu),則會(huì)拋出ClassFormatError。
加載階段是用戶參與的階段,我們可以自定義類加載器,去實(shí)現(xiàn)自己的類加載過程。
這是核心的步驟,簡(jiǎn)單說是把原始的類定義信息平滑地轉(zhuǎn)化入JVM運(yùn)行的過程中。這里可進(jìn)一步細(xì)分為三個(gè)步驟:
驗(yàn)證(Verification),這是虛擬機(jī)安全的重要保障,JVM需要核檢字節(jié)信息是符合Java虛擬機(jī)規(guī)范的,否則就被認(rèn)為是VerifyError。這樣就防止了惡意信息或者不合規(guī)的信息危害JVM的運(yùn)行。驗(yàn)證階段有可能觸發(fā)更多class的加載。
準(zhǔn)備(Preparation),創(chuàng)建類或接口中的靜態(tài)變量,并初始化靜態(tài)變量的初始值。但這里的“初始化”和下面的顯式初始化階段是有區(qū)別的,側(cè)重點(diǎn)在于分配所需要的內(nèi)存空間,不會(huì)去執(zhí)行更進(jìn)一步的JVM指令。
解析(Resolution),在這一步會(huì)將常量池中的符號(hào)引用(symbolic reference)替換為直接引用。在Java虛擬機(jī)規(guī)范中,詳細(xì)介紹了類、接口、方法和字段等各個(gè)方面的解析。
這一步真正去執(zhí)行類初始化的代碼邏輯,包括靜態(tài)字段復(fù)制的動(dòng)作,以及執(zhí)行類定義中的靜態(tài)初始化塊內(nèi)的邏輯。編譯器在編譯階段就會(huì)把這部分邏輯整理好,父類型的初始化邏輯優(yōu)先于當(dāng)前類型的邏輯。
啟動(dòng)類加載器(Bootstrap Class-Loader),加載jre/lib下面的jar文件,如rt.jar。它是個(gè)超級(jí)公民,即使是在開啟了Security Manager的時(shí)候,JDK仍賦予了它加載的程序AllPermission。
對(duì)于做底層開發(fā)的工程師,有的時(shí)候可能不得不去試圖修改JDK的基礎(chǔ)代碼,也就是通常意義上的核心類庫,我們可以使用下面的命令行參數(shù)。
# 指定新的 bootclasspath,替換 java.* 包的內(nèi)部實(shí)現(xiàn)
java -Xbootclasspath:<your_boot_classpath> your_App
# a 意味著 append,將指定目錄添加到 bootclasspath 后面
java -Xbootclasspath/a:<your_dir> your_App
# p 意味著 prepend,將指定目錄添加到 bootclasspath 前面
java -Xbootclasspath/p:<your_dir> your_App
用法其實(shí)很易懂,例如,使用最常見的“/p”,既然是前置,就有機(jī)會(huì)替換個(gè)別基礎(chǔ)類的實(shí)現(xiàn)。
我們一般可以使用下面方法獲取父加載器,但是在通常的JDK/JRE實(shí)現(xiàn)中,擴(kuò)展類加載器getParent()都只能返回null。
public final ClassLoader getParent()
擴(kuò)展類加載器(Extension or Ext Class-Loader),負(fù)責(zé)加載我們放到j(luò)re/lib/ext目錄下面的jar包,這就是所謂的extension機(jī)制。該目錄也可以通過設(shè)置“java.ext.dirs”來覆蓋
java -Djava.ext.dirs=your_ext_dir HelloWorld
應(yīng)用類加載器(Application or App Class-Loader),就是加載我們最熟悉的classpath的內(nèi)容。這里有一個(gè)容易混淆的概念,系統(tǒng)(System)類加載器,通常來說,其默認(rèn)就是JDK內(nèi)建的應(yīng)用類加載器,但是它同樣是可能修改的,比如:
java -Djava.system.class.loader=com.yourcorp.YourClassLoader HelloWorld
如果我們指定了這個(gè)參數(shù),JDK內(nèi)建的應(yīng)用類加載器就會(huì)成為定制加載器的父親,這種方式通常用在類似需要改變雙親委派模式的場(chǎng)景。
具體參考下圖:

談到類加載一個(gè)躲不開的話題就是“雙親委派模型”,簡(jiǎn)單說就是當(dāng)類加載器(Class-Loader)試圖加載某個(gè)類型的時(shí)候,除非父加載器找不到相應(yīng)的類型,否則盡量將這個(gè)任務(wù)代理給當(dāng)前加載器的父加載器去做。
參考上面這個(gè)結(jié)構(gòu)圖就很容易理解了。試想,如果不同類加載器都自己加載需要的某個(gè)類型,那么就會(huì)出現(xiàn)多次重復(fù)加載,完全是種浪費(fèi)。
通常類加載器機(jī)制有三個(gè)基本特征:
雙親委派模型。但不是所有類加載都遵守這個(gè)模型,有的時(shí)候,啟動(dòng)類加載器所加載的類型,是可能要加載用戶代碼的。比如JDK內(nèi)部的ServiceProvider/ServiceLoader機(jī)制,用戶可以在標(biāo)準(zhǔn)API框架上,提供自己的實(shí)現(xiàn),JDK也需要提供些默認(rèn)的參考實(shí)現(xiàn)。例如,Java中JNDI、JDBC、文件系統(tǒng)、Cipher等很多方面,都是利用的這種機(jī)制,這種情況就不會(huì)用雙親委派模型去加載,而是利用所謂的上下文加載器。
可見性。子加載器可以訪問父加載器加載的類型,但是反過來是不允許的。不然,因?yàn)槿鄙俦匾母綦x,我們就沒有辦法利用類加載器去實(shí)現(xiàn)容器的邏輯。
單一性。由于父加載器的類型對(duì)于子加載器是可見的,所以父加載器中加載過的類型,就不會(huì)在子加載器中重復(fù)加載。但是注意,類加載器“鄰居”間,同一類型仍然可以被加載多次,因?yàn)榛ハ嗖豢梢姟?/p>
“java類加載過程分為哪些步驟”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
新聞標(biāo)題:java類加載過程分為哪些步驟
網(wǎng)站網(wǎng)址:http://www.chinadenli.net/article16/igpggg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、ChatGPT、網(wǎng)站制作、關(guān)鍵詞優(yōu)化、、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)