當前位置:編程學習大全網 - 源碼下載 - 什麽是類加載?

什麽是類加載?

這裏我們從三個方面來談談java classloader。

1,翻譯classloader的相關技術文章(第9章。Security from Core Java Volume II),由於本人英語水平有限,難免不合適。請指出。

2.我們將從web應用的角度來模擬web應用的類加載器(這壹節是重點)。

3、通過測試2中實現的classloader來加深理解。

下面介紹壹下翻譯中的ClassLoader。

類加載器

JAVA編譯器將源代碼轉換成虛擬機器(我們稱之為虛擬機)的語言。虛擬機的指令保存在帶有類後綴的文件中。

每個類文件包含類和接口的定義以及實現代碼。這些類文件必須由程序解釋,程序可以將虛擬機的指令翻譯成

主機的機器語言。

註意:虛擬機只加載執行程序所需的類文件。例如,以執行MyProgram.class為例,運行虛擬機的步驟如下:

1,虛擬機有加載類文件的機制,比如從硬盤讀取文件或者從網絡獲取;虛擬機使用這種機制來加載MyProgram的類文件。

2.如果MyProgram有壹個實例變量或超類,那麽實例變量和超類的類文件也會被加載。

(加載壹個類所依賴的所有類的過程稱為解析該類->;自己看懂)

3,然後虛擬機執行MyProgram的main方法(因為是靜態方法,所以不需要new MyProgram的實例)。

4.如果main方法或main方法調用的方法需要其他類,這些類也會被加載。

類加載機制不僅僅是壹個類加載器,任何java程序都至少有以下三個類加載器(為了不影響大家的理解,這裏就不翻譯這三個類加載器的名字了)。

bootstrap class loader:加載系統類(jdk的rt.jar中的壹個典型類),它是虛擬機的重要部分,通常用c實現.

還有壹些類裝入器對象(即特定的類裝入器)與引導類裝入器沒有關聯。例如,String.class.getClassLoader()返回null。

擴展類加載器:加載jre/lib/ext目錄中的類。妳可以把妳的jar文件放在這個目錄下,擴展類加載器。

即使沒有設置類路徑,類也會被加載到jar中。(有些人建議使用這種機制來避免被類路徑所困擾,但是要註意以下警告)

系統類加載器(有時稱為應用程序加載器):加載應用程序類。

他主要加載類路徑目錄和jar/zip文件中的類,通過設置CLASSPATH環境變量或者在運行java時使用[-classpath]選項來指定類路徑。

在SUN的java實現中,擴展和系統類加載器都是用java實現的,都是URLClassLoader類的實例。

警告:如果您將jar文件放在jre/lib/ext目錄中,並且jar文件中的類需要加載壹個不是系統或擴展的類,

妳會有麻煩的。擴展類裝入器不使用類路徑。如果妳想管理jre/lib/ext下的類,請記住這壹點。

= = & gt如何理解這個:也就是說,如果妳把自己的x.jar放在jre/lib/ext下,如果要使用自己的x.jar中的類。

如果x.jar中沒有jre/lib/ext類,這個類將不會被加載。不難想象,因為妳的x.jar中的類是由擴展類加載器加載的。

加載後,他將不會加載類路徑路徑下的類。

警告:將jar文件放在jre/lib/ext目錄中還有第二個缺點:有時,程序員會忘記很久以前放在這個目錄中的類文件。

當類裝入器似乎忽略了類路徑(實際上並沒有,因為類裝入總是讓父類裝入器先裝入類,只有父類裝入器不能裝入)

它是自己加載的,“擴展類加載器是系統類加載器的父親,所以……”),

當加載擴展目錄中被遺忘已久的類時,他們會感到困惑。

類裝入器有父子關系,除了引導類裝入器之外,每個類裝入器都有壹個父類裝入器。

類裝入器將給予父裝入器裝入任何給定類的機會,如果父裝入器裝入失敗,它將自己裝入。

例如,當系統類加載器被要求加載壹個系統類(例如java.util.ArrayList)時,

然後,需要先加載擴展類加載器,擴展類加載器需要先加載bootstrap類加載器。

最後,rt.jar被bootstrap類加載器找到並加載,不需要其他類加載器再次搜索。

註意:當實現壹個類裝入器時,妳應該總是授權父裝入器裝入類。否則會有壹些潛在的安全隱患:自定義類加載器。

避免重要的安全檢查並意外加載系統類是可能的。

Applets、servlets和RMI存根是由用戶定義的類裝入器裝入的。妳甚至可以根據自己的需要編寫自己的類加載器。

這種方法允許您在將字節碼傳遞給虛擬機之前實現特殊的安全檢查。比如妳可以寫壹個拒絕加載無用的“付費”的類加載器。

下壹節將展示如何做到這壹點。

大多數時候,您不必擔心類裝入器。許多類被加載是因為它們被其他類引用,這個過程對妳是透明的。

如果在程序中調用Class.forName來加載壹個類,那麽調用class.forname的類的加載器就會加載壹個新的類,通常情況下,

這不成問題。但是,在下列情況下,它會失敗:

1.當您的庫使用Class.forName方法實現壹個類時。

2.當妳的lib中的類的方法被壹個不同的類加載器加載的應用類調用時(這個首先需要很好的理解)。

3.當加載的類對應用程序的類加載器不可見時(也就是說,類路徑下沒有相關的類)。

在這種情況下,庫類需要搜索應用程序類加載器(代碼如下):

thread t = thread . currentthread();

class loader loader = t . getcontext class loader();

class cl = loader . load class(class name);

使用類裝入器作為名稱空間

任何java程序員都知道包名是用來消除名稱沖突的。標準類庫中有兩個名為Date的類(java.util.Date和java.sql.Date)。

壹個簡單的名字(這裏,妳直接在程序中寫日期)只是為了方便程序員,需要包含import語句。在運行的程序中,

所有類都包含它們的包名。

這可能會讓您感到驚訝,但是,您可以在同壹個虛擬機中擁有兩個具有相同類名和包名的類。類由其全名和類裝入器來標識。

這項技術對於從多個來源加載代碼非常有用。例如,瀏覽器對每個網頁使用單獨的。

Applet類加載器。這允許虛擬機從不同的網頁中分離出類,不管它們是如何命名的。

註意:這項技術還有其他用途,比如塞夫萊特和EJB的熱部署。請參考:/developer/tech tips/2000/TT 1027 . html。

編寫自己的類裝入器

ClassLoader超類的loadClass方法負責委托

僅當類尚未被加載並且

如果父類裝入器不能裝入該類。

要定義自己的類加載器,只需繼承類加載器類並覆蓋findClass(String className)方法。

類加載器父類的loadClass方法負責授權父類加載器,並且僅當它還沒有被加載並且父類加載器不能加載它時。

調用findClass方法。

註意:在JDK的早期版本中,程序員不得不重寫loadClass方法。不再推薦這樣做。

要實現findClass方法,必須做兩件事。

1,從文件或者其他地方加載類的字節碼。

2.為了向虛擬機提交字節碼,需要調用ClassLoader類的defineClass方法。

  • 上一篇:-1-A 火山巖分類命名標準
  • 下一篇:誰知道能錄制視頻聊天動態畫面的軟件.我試用的好幾個都只能錄制鼠標的操作,視頻那壹片是黑的.謝謝
  • copyright 2024編程學習大全網