小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

超詳細(xì)java類加載器學(xué)習(xí)總結(jié)

 頭號(hào)碼甲 2022-12-20 發(fā)布于北京

上一篇,我們?cè)敿?xì)講解了java類的加載機(jī)制,本篇我們繼續(xù)講解java類加載器的內(nèi)容。
本文學(xué)習(xí)目錄:
什么是類加載器?
類加載器的樹狀層次結(jié)構(gòu)
類加載器的工作原理
雙親委派模型
類加載的過程

一、 什么是類加載器?
類加載器(class loader)用來加載 Java 類到 Java 虛擬機(jī)中。一般來說,Java 類的虛擬機(jī)使用 Java 方式如下:Java 源程序(.java 文件)在經(jīng)過 Java 編譯器編譯之后就被轉(zhuǎn)換成 Java 字節(jié)代碼(.class 文件)。類加載器負(fù)責(zé)讀取 Java 字節(jié)代碼,并轉(zhuǎn)換成 java.lang.Class類的一個(gè)實(shí)例。每個(gè)這樣的實(shí)例用來表示一個(gè) Java 類。通過此實(shí)例的 newInstance()方法就可以創(chuàng)建出該類的一個(gè)對(duì)象。實(shí)際的情況可能更加復(fù)雜,比如 Java 字節(jié)代碼可能是通過工具動(dòng)態(tài)生成的,也可能是通過網(wǎng)絡(luò)下載的。

二、類加載器的樹狀層次結(jié)構(gòu)

Java 中的類加載器大致可以分成兩類,一類是系統(tǒng)提供的,另外一類則是由 Java 應(yīng)用開發(fā)人員編寫的。

類加載器的樹狀層次結(jié)構(gòu)圖

1.引導(dǎo)類加載器(bootstrap class loader):

它用來加載 Java 的核心庫(jre/lib/rt.jar),是用原生C++代碼來實(shí)現(xiàn)的,并不繼承自java.lang.ClassLoader。加載擴(kuò)展類和應(yīng)用程序類加載器,并指定他們的父類加載器,在java中獲取不到。

2.擴(kuò)展類加載器(extensions class loader):

它用來加載 Java 的擴(kuò)展庫(jre/ext/*.jar)。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。

3.系統(tǒng)類加載器(system class loader):

它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應(yīng)用的類都是由它來完成加載的??梢酝ㄟ^
ClassLoader.getSystemClassLoader()來獲取它。

4.自定義類加載器(custom class loader):

除了系統(tǒng)提供的類加載器以外,開發(fā)人員可以通過繼承 java.lang.ClassLoader類的方式實(shí)現(xiàn)自己的類加載器,以滿足一些特殊的需求。

測(cè)試代碼案例:

輸出結(jié)果:

測(cè)試案例可以看出ClassLoader類是由AppClassLoader加載的。他的父親是ExtClassLoader,ExtClassLoader的父親無法獲取是因?yàn)樗怯肅++實(shí)現(xiàn)的。

三、類加載器的工作機(jī)制

虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機(jī)直接使用的Java類型,這就是虛擬機(jī)的類加載機(jī)制。

類加載器就是尋找類的字節(jié)碼文件并構(gòu)造出類在JVM內(nèi)部表示的對(duì)象組件。在java中,類加載器把一個(gè)類裝入JVM中,要經(jīng)過以下步驟:

1.裝載:查找和導(dǎo)入Class文件;

2.鏈接:執(zhí)行校驗(yàn)、準(zhǔn)備和解析步驟,其中解析步驟是可以選擇的;

(1)校驗(yàn):檢查載入Class文件數(shù)據(jù)的正確性;

(2)準(zhǔn)備:給累的靜態(tài)變量分配存儲(chǔ)空間;

(3)解析:將符號(hào)引用轉(zhuǎn)成直接引用;

3.初始化:對(duì)類的靜態(tài)變量、靜態(tài)代碼塊執(zhí)行初始化工作。

類加載工作由ClassLoader及其子類負(fù)責(zé),ClassLoader是一個(gè)重要的java運(yùn)行時(shí)系統(tǒng)組件,他負(fù)責(zé)在運(yùn)行時(shí)查找和裝入Class字節(jié)碼文件。JVM在運(yùn)行時(shí)會(huì)產(chǎn)生三個(gè)ClassLoader:根裝載器、擴(kuò)展類加載器和應(yīng)用程序類加載器。其中根裝載器不是ClassLoader的子類,它是由C++語言編寫,因此我們?cè)趈ava中看不到它。根裝載器負(fù)責(zé)裝載JRE的核心類庫,如JRE目標(biāo)下的大rt.jar、charsets.jar等。擴(kuò)展類加載器和應(yīng)用程序類加載器都是ClassLoader的子類,其中擴(kuò)展類加載器負(fù)責(zé)裝載JRE擴(kuò)展目錄ext中的JAR類包;應(yīng)用程序類加載器負(fù)責(zé)加載Classpath路徑下的類包。

四、雙親委派模型

雙親委派模型過程

某個(gè)特定的類加載器在接到加載類的請(qǐng)求時(shí),首先將加載任務(wù)委托給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務(wù),就成功返回;只有父類加載器無法完成此加載任務(wù)時(shí),才自己去加載。

使用雙親委派模型的好處在于Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系。例如類java.lang.Object,它存在在rt.jar中,無論哪一個(gè)類加載器要加載這個(gè)類,最終都是委派給處于模型最頂端的Bootstrap ClassLoader進(jìn)行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個(gè)類。相反,如果沒有雙親委派模型而是由各個(gè)類加載器自行加載的話,如果用戶編寫了一個(gè)java.lang.Object的同名類并放在ClassPath中,那系統(tǒng)中將會(huì)出現(xiàn)多個(gè)不同的Object類,程序?qū)⒒靵y。因此,如果開發(fā)者嘗試編寫一個(gè)與rt.jar類庫中重名的Java類,可以正常編譯,但是永遠(yuǎn)無法被加載運(yùn)行。

雙親委派模型的系統(tǒng)實(shí)現(xiàn)

在java.lang.ClassLoader的loadClass()方法中,先檢查是否已經(jīng)被加載過,若沒有加載則調(diào)用父類加載器的loadClass()方法,若父加載器為空則默認(rèn)使用啟動(dòng)類加載器作為父加載器。如果父加載失敗,則拋出ClassNotFoundException異常后,再調(diào)用自己的findClass()方法進(jìn)行加載。

五、類加載器的過程

首先我們先看一下類加載器過程圖,如下:

java類加載器過程圖

類加載器的過程包括了三個(gè)大步驟,他們分別是:

加載

1.加載指的是將類的class文件讀入到內(nèi)存,并為之創(chuàng)建一個(gè)java.lang.Class對(duì)象。

2.通過類的全限定名獲取此類的二進(jìn)制字節(jié)流。

3.將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。

4.在內(nèi)存中生成一個(gè)Class對(duì)象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)的訪問入口。

加載通常由類加載器完成,加載類的方式具體有以下幾項(xiàng):

1.本地資源加載。

2.網(wǎng)絡(luò)加載。Web Applet。

3.zip壓縮包加載。jar,war。

4.運(yùn)行時(shí)計(jì)算生成。動(dòng)態(tài)代理技術(shù)。

5.其他文件生成。JSP應(yīng)用。

6.從加密文件中讀取,主要是為了防止class文件被反編譯。

鏈接

鏈接分為三個(gè)步驟:

1.驗(yàn)證

確保class文件的字節(jié)流中包含信息符合虛擬機(jī)要求。

主要包括,文件格式驗(yàn)證,元數(shù)據(jù)驗(yàn)證,字節(jié)碼驗(yàn)證,符號(hào)引用驗(yàn)證。

2.準(zhǔn)備

為類變量分配內(nèi)存,并為變量賦零值。

這里不包括用final修飾的static,因?yàn)閒inal在變異的時(shí)候就會(huì)分配了,準(zhǔn)備階段會(huì)顯式初始化。不會(huì)為實(shí)例變量分配初始化。

3.解析

將常量池內(nèi)的符號(hào)引用變?yōu)橹苯右谩?/p>

初始化

初始化階段就是執(zhí)行類構(gòu)造器方法()方法。

()方法是由javac將類變量賦值動(dòng)作和靜態(tài)代碼塊中的語句合并自動(dòng)產(chǎn)生的。當(dāng)類不存在類變量和靜態(tài)代碼塊時(shí)不會(huì)自動(dòng)生成此方法。一個(gè)類只會(huì)被加載一次,()方法是同步加鎖的。

總結(jié)了這么多,你學(xué)會(huì)了嗎?

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多