四虎影视库国产精品一区-四虎影视库-四虎影视久久久免费-四虎影视久久久-四虎影视久久-四虎影视精品永久免费网站

TEL:15195455103

Java培訓 > Java知識 >
同類推薦

深入討論下Java類加載器

作者:南京????來源:南京????發布時間:2020-01-09 09:03????瀏覽量:113

  類加載器是 Java 語言的一個創新,也是 Java 語言流行的重要原因之一。它使得 Java 類可以被動態加載到 Java 虛擬機中并執行。類加載器從 JDK 1.0 就出現了,初是為了滿足 Java Applet 的需要而開發出來的。Java Applet 需要從遠程下載 Java 類文件到瀏覽器中并執行。現在類加載器在 Web 容器和 OSGi 中得到了廣泛的使用。一般來說,Java 應用的開發人員不需要直接同類加載器進行交互。Java 虛擬機默認的行為就已經足夠滿足大多數情況的需求了。不過如果遇到了需要與類加載器進行交互的情況,而對類加載器的機制又不是很了解的話,就很容易花大量的時間去調試 ClassNotFoundException和 NoClassDefFoundError等異常。本文將詳細介紹 Java 的類加載器,幫助讀者深刻理解 Java 語言中的這個重要概念。下面首先介紹一些相關的基本概念。

  類加載器基本概念

  顧名思義,類加載器(class loader)用來加載 Java 類到 Java 虛擬機中。一般來說,Java 虛擬機使用 Java 類的方式如下:Java 源程序(.java 文件)在經過 Java 編譯器編譯之后就被轉換成 Java 字節代碼(.class 文件)。類加載器負責讀取 Java 字節代碼,并轉換成 java.lang.Class類的一個實例。每個這樣的實例用來表示一個 Java 類。通過此實例的 newInstance()方法就可以創建出該類的一個對象。實際的情況可能更加復雜,比如 Java 字節代碼可能是通過工具動態生成的,也可能是通過網絡下載的。

  基本上所有的類加載器都是 java.lang.ClassLoader類的一個實例。下面詳細介紹這個 Java 類。

  java.lang.ClassLoader類介紹

  java.lang.ClassLoader

  類的基本職責就是根據一個指定的類的名稱,找到或者生成其對應的字節代碼,然后從這些字節代碼中定義出一個 Java 類,即 java.lang.Class類的一個實例。除此之外,ClassLoader還負責加載 Java 應用所需的資源,如圖像文件和配置文件等。不過本文只討論其加載類的功能。為了完成加載類的這個職責,ClassLoader提供了一系列的方法,關于這些方法的細節會在下面進行介紹。

  getParent() 返回該類加載器的父類加載器。

  loadClass(String name) 加載名稱為 name的類,返回的結果是 java.lang.Class類的實例。

  findClass(String name) 查找名稱為 name的類,返回的結果是 java.lang.Class類的實例。

  findLoadedClass(String name) 查找名稱為 name的已經被加載過的類,返回的結果是 java.lang.Class類的實例。

  defineClass(String name, byte[] b, int off, int len) 把字節數組 b中的內容轉換成 Java 類,返回的結果是 java.lang.Class類的實例。這個方法被聲明為 final的。

  resolveClass(Class c) 鏈接指定的 Java 類。

中博教育軟件學校

  對于上面給出的方法,表示類名稱的 name參數的值是類的二進制名稱。需要注意的是內部類的表示,如 com.example.Sample$1和 com.example.Sample$Inner等表示方式。這些方法會在下面介紹類加載器的工作機制時,做進一步的說明。

  類加載器的樹狀組織結構。

  Java 中的類加載器大致可以分成兩類,一類是系統提供的,另外一類則是由 Java 應用開發人員編寫的。系統提供的類加載器主要有下面三個:

  引導類加載器(bootstrap class loader):它用來加載 Java 的核心庫,是用原生代碼來實現的,并不繼承自 java.lang.ClassLoader。

  擴展類加載器(extensions class loader):它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。

  系統類加載器(system class loader):它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()來獲取它。

  除了系統提供的類加載器以外,開發人員可以通過繼承 java.lang.ClassLoader

  類的方式實現自己的類加載器,以滿足一些特殊的需求。

  除了引導類加載器之外,所有的類加載器都有一個父類加載器。通過 getParent()方法可以得到。對于系統提供的類加載器來說,系統類加載器的父類加載器是擴展類加載器,而擴展類加載器的父類加載器是引導類加載器;對于開發人員編寫的類加載器來說,其父類加載器是加載此類加載器 Java 類的類加載器。因為類加載器 Java 類如同其它的 Java 類一樣,也是要由類加載器來加載的。一般來說,開發人員編寫的類加載器的父類加載器是系統類加載器。類加載器通過這種方式組織起來,形成樹狀結構。樹的根節點就是引導類加載器。中給出了一個典型的類加載器樹狀組織結構示意圖,其中的箭頭指向的是父類加載器。

  在了解了類加載器的樹狀組織結構之后,下面介紹類加載器的代理模式。

  類加載器在嘗試自己去查找某個類的字節代碼并定義它時,會先代理給其父類加載器,由父類加載器先去嘗試加載這個類,依次類推。在介紹代理模式背后的動機之前,首先需要說明一下 Java 虛擬機是如何判定兩個 Java 類是相同的。Java 虛擬機不僅要看類的全名是否相同,還要看加載此類的類加載器是否一樣。只有兩者都相同的情況,才認為兩個類是相同的。即便是同樣的字節代碼,被不同的類加載器加載之后所得到的類,也是不同的。(相關推薦:java這朵永生花將長存

  比如一個 java類 com.example.Sample,編譯之后生成了字節代碼文件 Sample.class。兩個不同的類加載器 ClassLoaderA和 ClassLoaderB分別讀取了這個 Sample.class文件,并定義出兩個 java.lang.Class類的實例來表示這個類。這兩個實例是不相同的。對于 Java 虛擬機來說,它們是不同的類。試圖對這兩個類的對象進行相互賦值,會拋出運行時異常 ClassCastException。


本文內容、圖片由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至2353260942@qq.com 舉報,一經查實,本站將立刻刪除。(如需投稿聯系管理員開通!)

? CopyRight njjava.com ???? 蘇ICP備14052071號

搶試聽名額

名額僅剩66名

教育改變生活

WE CHANGE LIVES