Goingmm

            BlogJava :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理 ::
            82 隨筆 :: 15 文章 :: 452 評論 :: 0 Trackbacks

          類裝載器負責把類裝入 Java 虛擬機(JVM)。簡單的應用程序可以用 Java 平臺內置的類裝載工具裝載類;更復雜的應用程序則傾向于定義自己定制的類裝載器。但是,不論使用哪種類裝載器,在類裝載過程中都可能發生許多問題。如果想避免這類問題,需要理解類裝載的基本機制。

           

          類裝載器委托模型

          classload.gif 

          注意:在這個繼承體系中,父類裝載器始終具有優先裝載的權力。比如子類接收到需要裝載Person類的請求,它會先委托給父類去嘗試裝載,父類裝載失敗,子類才會接著嘗試裝載。但是,都被規定了各自的裝載空間。[例如:“System Class Loader” 不會到/jre/lib/* 下去load]

           

          引導類裝載器(也稱作基本(primordial 類裝載器):

          它本身是C++寫的程序。可以獨立運行,它是JVM的運行起點。不能由 Java 代碼實例化。(通常是因為它是作為 VM 本身的一部分實現的。)這個類裝載器可以從啟動的類路徑裝載核心系統類,通常是位于 jre/lib 目錄的 JAR 文件。

          擴展(extension 類裝載器(也稱作標準擴展 類裝載器):

          是引導類裝載器的一個孩子。它的主要職責是從擴展目錄裝載類,通常位于 jre/lib/ext 目錄。這提供了簡單地訪問新擴展的能力,例如不同的安全擴展,不需要修改用戶的類路徑即可實現。

          系統(system 類裝載器(也稱作應用程序 類裝載器):

          負責從 CLASSPATH 環境變量指定的路徑裝載代碼。默認情況下,這個類裝載器是用戶創建的任何類裝載器的父類。這也是 ClassLoader.getSystemClassLoader() 方法返回的類裝載器。

           

          類裝載的階段

          一個類的運行,JVM做會以下幾件事情: 1、類裝載 2、鏈接 3、初始化 4、實例化

          一個類的裝載可分成三個階段:類裝載、鏈接和初始化

           

          類裝載的 階段示意圖

          loadstep.gif
             裝載
          階段包括:找到必要的類(通過查找每個類路徑)并裝載字節碼。在 JVM 中,裝載階段為類對象提供了非常基本的內存結構。在這一階段不處理方法、字段和引用的其他類。所以,類還不能使用。

           

             鏈接 是三個階段中最復雜的一個。可以把它分成三個主要階段:

          • 字節碼驗證。 類裝載器對于類的字節碼要做許多檢測,以確保格式正確、行為正確。
          • 類準備。 這個階段準備代表每個類中定義的字段、方法和實現接口所必需的數據結構。
          • 解析。   這個階段,類裝載器裝載類所引用的其他所有類。可以用許多方式引用類:
            • 超類
            • 接口
            • 字段
            • 方法簽名
            • 方法中使用的本地變量

             在初始化 階段,類中包含的靜態初始化器都被執行。在這一階段末尾,靜態字段被初始化成默認值。
             
          在這三個階段末尾,類被完整地裝載,可以使用了。請注意可以用惰性方式執行類裝載,所以類裝載過程的某些部分可能在第一次使用類的時候[比如:初始化]才執行,而不是在裝載時執行。

          舉例說明:

                   Class.forName(args[0], false,off.getClass().getClassLoader());

          告訴JVM不需在load class之后進行initial的工作。這樣,將initial的工作推遲到了newInstance的時候進行。所以,static塊的絕對不是“只在類被第一次實例化的時候才會被僅僅調用一次”,而應

          該是在類被初始化的時候,僅僅調用一次

                   Class.forName(args[0], true,off.getClass().getClassLoader());

                   告訴JVMload class之后立即進行initial的工作

           

          顯式裝載與隱式裝載

          類裝載的方式有兩種 —— 顯式 隱式,兩者之間有些細微差異。

          顯式 類裝載發生在使用以下方法調用裝載的類的時候:

          • cl.loadClass()cl java.lang.ClassLoader 的實例)
          • Class.forName()(啟動的類裝載器是當前類定義的類裝載器)

             當調用其中一個方法的時候,指定的類(以類名為參數)由類裝載器裝載。如果類已經裝載,那么只是返回一個引用;否則,裝載器會通過委托模型裝載類。

             隱式 類裝載發生在由于引用、實例化或繼承導致裝載類的時候(不是通過顯式方法調用)。在每種情況下,裝載都是在幕后啟動的,JVM 會解析必要的引用并裝載類。與顯式類裝載一樣,如果類已經裝載了,那么只是返回一個引用;否則,裝載器會通過委托模型裝載類。例如:Person p = new Person();

              類的裝載通常組合了顯式和隱式類裝載。例如,類裝載器可能先顯式地裝載一個類,然后再隱式地裝載它引用的所有類。

           

          參考:IBM技術文檔

           

          Goingmm 2006-2-23 

           

          posted on 2006-02-23 09:51 Goingmm 閱讀(492) 評論(0)  編輯  收藏 所屬分類: Reading Note
          主站蜘蛛池模板: 新竹市| 武山县| 遵化市| 抚顺县| 乾安县| 贵阳市| 子长县| 临高县| 蒙山县| 永平县| 廉江市| 娄底市| 怀远县| 耒阳市| 长葛市| 阳曲县| 宣武区| 左贡县| 开平市| 莎车县| 缙云县| 皋兰县| 密云县| 涡阳县| 广水市| 泸州市| 准格尔旗| 内黄县| 县级市| 昆山市| 苍山县| 漳平市| 宜阳县| 莱芜市| 桓台县| 永和县| 栾城县| 邛崃市| 峡江县| 综艺| 石门县|