Java中的ClassLoader

? Java中類的加載過程(如Dog類):

?

  1. 通過類型信息定位Dog.class文件。
  2. 載入Dog.class文件,創建相應的Class對象。
  3. 執行父類的靜態字段定義時初始化語句和父類的靜態初始化塊。
  4. 執行子類的靜態字段定義時初始化語句和子類的靜態初始化塊。
  5. 當使用new Dog()方式時,在堆上為Dog對象分配存儲空間,并清零分配的存儲空間。
  6. 執行父類的字段定義時初始化語句和父類的構造函數。
  7. 執行子類的字段定義時初始化語句和子類的構造函數。

(參考Java編程思想,部分是自己測試的結果,還沒有看到相關資料,這個順序和C#的順序好像有比較大的差別)

?

我們知道每個Java類編譯后會生成一個.class文件,里面除了存儲了類的字節碼之外,還存儲了和該類對應的Class對象的信息(包含一些用于反射的信息)。在JVM中,通過類加載器(ClassLoader)來實現Class對象的創建。

?

在Object類中有public的getClass()方法,我們可以通過該方法獲取與之對應的Class對象。在獲取類對應的Class對象后,我們就可以通過newInstance()方法或者通過獲取其Constructor的方法來創建該類的實例,也可以通過Class對象獲取類或實例相關的更多信息,如方法,字段等,即反射的功能。另外我們也可以通過Class.forName()方法,通過傳入類字符串的方式來創建類的實例。(通過Class對象創建類實例和通過forName方法創建類實例是否有聯系呢?這兩種創建類的實例和直接通過new創建類實例是否也有聯系呢?)

?

然而Dog.class文件是如何定位的?Dog.class文件是如何被加載并解析的?Class對象又是如何生成的呢?這就是ClassLoader需要解決的問題,也是這篇文章中接下來要講述的。

?

ClassLoader的工作原理

?

在Java內部實現了三種類型的ClassLoader:Bootstrap ClassLoader,Extension ClassLoader,?System ClassLoader。這三個ClassLoader通過parent形成一條單向鏈,其中Bootstrap處于鏈尾,而System ClassLoader處于鏈頭。

?

Bootstrap ClassLoader

Bootstrap ClassLoader用于在啟動JVM時加載類,以使JVM能正常工作,因而它是用Native代碼實現的,最早被創建出來,處于最底層。

Bootstrap ClassLoader將搜索Java核心庫(%JAVA_HOME%\jre\lib),如rt.jar、i18n.jar等,在這些核心庫中包含了Java的核心類,即Bootstrap ClassLoader用于加載Java的核心類,包括java.lang、java.io等包中的類。

?

Extension ClassLoader

Extension ClassLoader位于鏈的中間層,它將搜索特定的標準擴展目錄。該標準擴展目錄在不同的JVM實現中不一定相同,在sun的JVM中,它是%JRE_HOME% \lib\ext,具體路徑可以通過java.ext.dirs系統屬性值獲取。該標準擴展目錄存在的目的在于擴展和共享,應用程序廠商可以將部分共享庫放置于此,而不是各自程序的目錄下的多份拷貝。在開發過程中,我們也可以把部分常用的庫放置于此,而不必每次都去配置環境。

?

System ClassLoader

System ClassLoader位于鏈的最頂層,它將搜索CLASSPATH中配置的目錄和jar文件。

?

三種ClassLoader的協同工作

既然系統中有三種不同的ClassLoader,那么一個類的加載是用那個ClassLoader呢?在Java中,是通過“代理模型(delegation model)”來決定使用哪個ClassLoader來加載類的(讀取.class文件,并創建相應的Class對象)。當一個類需要被加載的時候,系統默認通過System ClassLoader來加載該類;然而System ClassLoader并不立即加載該類,它會將加載的行為代理給其parent去加載,只有當其parent不能加載該類的時,System ClassLoader才去搜索CLASSPATH中的目錄和jar文件以加載該類,若找到對應的.class文件,則加載該類,否則拋出ClassNotFoundException。當它將加載的行為代理給Extension ClassLoader并最終代理給Bootstrap ClassLoader的時候,他們也做的是相似的事情。從設計的角度,這其實就是一種職責鏈模式(Chain of Responsibility Pattern

?

那么Java為什么需要這種代理模型呢?答案是出于安全的考慮。Java是一種安全的編程語言,它會對每個加載的類執行安全檢查,但是對Java核心庫中的類是不執行安全檢查的(即他們是受JVM信賴的)。(什么是安全檢查?以我現在所知,就是用戶可以通過security manager來控制特定目錄的訪問權限,如何使用這些控制將會是另一個主題。對安全檢查是否還有其他的呢?)那么假如用戶可以加載自己編寫的和核心庫同名的類(如java.lang.Object),那么這些用戶編寫的類就可以繞過安全檢查,從而為一些惡意用戶提供了一種破壞的途徑。然而在使用這種代理模型后,類的加載首先會代理到Bootstrap ClassLoader中實行加載,如果它發現當前核心類庫中可以加載對應的類,系統會加載核心庫中的類,而不會加載用戶編寫的類。

?

但是如果只是這樣,還不足以保證類的加載的安全。因為用戶完全可以定義自己的ClassLoader,在自己的ClassLoader中破壞這種代理模型,那么用戶自己寫的java.lang.Object就可以被加載了。為了解決這個問題,在Java中認為兩個類名相同的實例,如果加載他們的ClassLoader不同,那么他們是不同的類型,即他們之間不能轉換,而且用instanceof操作符返回的是false。這樣的話,即使用戶加載了自己的java.lang.Object類,它也不是系統認為可以信賴的java.lang.Object,那么它就繞不過安全檢查機制。(以上的描述只是我的猜想,我還沒有看到相關的資料提到該問題,因而有待驗證。)

?

有人說使用這種機制可以實現兼容性的升級,在軟件的舊版本中使用某個舊版本的類,在升級的某些新部分中可以使用相同類的新版本,即實現內存中保留一個類的兩個版本。我認為這種不應該是一種推薦的做法,在內存中保留一個類的兩個版本極易在運行是引起一些莫名其妙的錯誤。

?

很可惜,我沒能找到以上三種ClassLoader的源碼,看不了內部的實現。在Java中,它們都是通過ClassLoader這個抽象類來表示的。以下簡單的介紹一下ClassLoader內部的成員

(其中Extension ClassLoader的實現類為:sun .misc.Launcher$ExtClassLoader)

?

來自?http://dlevin.iteye.com/blog/772604

轉載于:https://www.cnblogs.com/hellocyc/p/4409722.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259097.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259097.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259097.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

excel刪除無盡空白行_excel如何批量刪除空白行 巧用 ctrl+G 只需1秒 最常用的技巧...

工作中我們使用excel通常都會遇到這種情況,就是表格中有很多多余的空行。我們需要把多余的空行刪除。 如果空行只有一兩行的話,可以把鼠標放在空白行上,然后點擊鼠標右鍵,在彈出的菜單中選擇刪除菜單。 在彈出的刪除確定窗口中&am…

Doxygen for C++使用說明——注釋代碼一

寫這一節的時候,我在想網上有眾多的參考文獻,外加官網上的,要是我再將它們重復一遍,也沒什么意思。網上資料很多,但是他們有一個共同的缺點是都是羅列用法,然后顯示效果。這些都是比較散的,我想…

DevOps的前世今生

2019獨角獸企業重金招聘Python工程師標準>>> 目前在國外,互聯網巨頭如Google、Facebook、Amazon、LinkedIn、Netflix、Airbnb,傳統軟件公司如Adobe、IBM、Microsoft、SAP等,亦或是網絡業務非核心企業如蘋果、沃爾瑪、索尼影視娛樂…

【轉】最牛B的編碼套路

最近,我大量閱讀了Steve Yegge的文章。其中有一篇叫“Practicing Programming”(練習編程),寫成于2005年,讀后令我驚訝不已: 與你所相信的恰恰相反,單純地每天埋頭于工作并不能算是真正意義上的…

ecshop 廣告設置

最近公司準備做個商城,讓我從JAVA轉過去,好吧,先看下吧,反正也得做。接到手里的是一套已經成型的模板,但是二次開發必須得了解下機制、文件、響應、設置什么的,也是個新手,寫點東西給后面更新的…

linux 信號_Linux信號機制

信號就是一條消息,通知進程系統中發生了什么事,每種信號都對應著某種系統事件。一般的底層硬件異常是由內核的異常處理程序處理的,它對用戶進程來說是透明的。而信號機制,提供了一種方法通知用戶進程發生了這些異常。例如&#xf…

DOxygen for C++使用說明——添加數學公式

公式 Doxygen允許你把 公式顯示在最終的輸出中(這個功能僅限于HTML和輸出).為了可以在HTML documentation顯示公式(轉化為圖片),你必須安裝以下軟件: latex: 編譯器, 被用來解析公式, 首先提取公式寫到一…

VC2010下Qt5的中文亂碼問題

要搞清楚這個問題,先要弄明白編碼。但是編碼問題實在太復雜,這里肯定講不開。 我先找一個例子,比如:“中文” 的 Unicode 碼點/UTF8編碼/GBK 分別是多少。 先去這個網站,輸入 “中文” 查詢對應的 Unicode 碼點/UTF8編…

Tomcat 的 DefaultServlet

問題描述: 群里有人測試 Spring MVC,沒有配置任何Controller,只配置了一個view resolver,指定了前綴后綴。 然后,他問的是 當訪問 localhost:8080/test 的時候,為什么會被重定向到 localhost:8080/test/ &a…

Python學習(七)面向對象 ——封裝

Python 類的封裝 承接上一節,學了Student類的定義及實例化,每個實例都擁有各自的name和score。現在若需要打印一個學生的成績,可定義函數 print_score() 該函數為類外的函數,如下: 1 class Student(object):2 def …

spss練習數據_SPSS篇——如何在成千上百萬個數據中標識重復個案

本文就帶大家來學習一個小技巧,如何運用SPSS標識重復個案。我們都知道在Excel中,通常會用到“篩選”功能來選出指定條件相同的單元格。那么在SPSS中,如何在成千上百萬個數據中篩選出重復的個案呢? 小編就是要告訴你,幾…

DOxygen for C++使用說明——Markdown支持

自Doxygen 版本1.8.0,Markdown被引進。 接下來,我們將先簡單介紹標準的Markdown語法,讀者可以進入Markdown官網查詢更詳細的細節。然后討論一下Doxygen支持的Markdown擴展,最后討論一下Doxygen對Markdown標準的實現細節。 Stand…

方程式漏洞之復現window2008/win7 遠程命令執行漏洞

前幾天就想寫的,因為一些緣故就沒寫。此次是在外網環境下進行的。大家在內網中也一個樣。 方法: 使用Eternalblue模塊,劍測是否有漏洞然后msf生成一個dll直接反彈shell. PS:win版本的不知道緣何生成出來的dll是0kb 我就在自己本地…

C++空類和string類

1. 空類 1.1 空類默認哪六個成員函數。 1 class Empty2 {3 public:4 Empty(); //缺省構造函數 Empty e;5 Empty( const Empty& ); //拷貝構造函數 Empty e2(e1);6 ~Empty(); //析構函數7 Empty& operator( const Empty& ); //賦值運算符…

客服會話 小程序 如何發起_小程序、公眾號、App三者如何融合布局?這里有一份避坑指南...

對產品經理來說,小程序無疑是2020年最火爆的詞之一了。我們能看到,就在今年疫情期間,小程序DAU達到4.5億,而超市、生鮮果蔬、社區購物等都同比增長100個點左右,小程序的商業價值很明顯地在快速釋放。小程序如此火爆&am…

DOxygen for C++使用說明——注釋代碼二

這一次我在谷歌搜索中檢索到了Doxygen在github的倉庫,進去一看,令人大喜,github倉庫里含有了一個Doxygen的官方配置文件Doxyfile,于是下載下來,發現Doxyfile已經配置了將倉庫中的\src文件編譯成Documentation,并且將結果放在了dox…

python super()(轉載)

一、問題的發現與提出 在Python類的方法(method)中,要調用父類的某個方法,在Python 2.2以前,通常的寫法如代碼段1: 代碼段1: class A:def __init__(self):print "enter A"print "…

Swagger+Spring mvc生成Restful接口文檔

2019獨角獸企業重金招聘Python工程師標準>>> Swagger 是一個規范和完整的框架,用于生成、描述、調用和可視化 RESTful 風格的 Web 服務。總體目標是使客戶端和文件系統作為服務器以同樣的速度來更新。文件的方法,參數和模型緊密集成到服務器端…

JavaScript——變量與基本數據類型

前言 JavaScript中的變量為松散類型,所謂松散類型就是指當一個變量被申明出來就可以保存任意類型的值,就是不像SQL一樣申明某個鍵值為int就只能保存整型數值,申明varchar只能保存字符串。一個變量所保存值的類型也可以改變,這在Ja…

vscode可以打開jupyternotebook嗎_剛剛,官方宣布 VS Code 支持 Python 全開發了!

關注Python高校每天早上23:10準時推送北京時間 2019 年 9 月 21 日,PyCon China 2019 在上海舉行。在下午的演講中,來自微軟開發工具事業部的資深研發工程師韓駿做了主題為《Python 與 Visual Studio Code 在人工智能應用中的最佳 Azure 實踐》的演講。在…