<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] ## 動態加載 Java程序在運行時并不一定被完整加載,只有當發現該類還沒有加載時,才去本地或遠程查找類的.class文件并驗證和加載; 當程序創建了第一個對類的靜態成員的引用(如類的靜態變量、靜態方法、構造方法——構造方法也是靜態的)時,才會加載該類。Java的這個特性叫做:動態加載。 ### 一個類的初始化包括3個步驟 * 加載(Loading),由類加載器執行,查找字節碼,并創建一個Class對象(只是創建); * 鏈接(Linking),驗證字節碼,為靜態域分配存儲空間(只是分配,并不初始化該存儲空間),解析該類創建所需要的對其它類的應用; * 初始化(Initialization),首先執行靜態初始化塊static{},初始化靜態變量,執行靜態方法(如構造方法)。 根據java虛擬機規范,所有java虛擬機實現必須在每個類或接口被java程序首次主動使用時才初始化。 ### 主動使用有以下6種: * 創建類的實例 * 訪問某個類或者接口的靜態變量,或者對該靜態變量賦值(如果訪問靜態編譯時常量(即編譯時可以確定值的常量)不會導致類的初始化) * 調用類的靜態方法 * 反射(Class.forName(xxx.xxx.xxx)) * 初始化一個類的子類(相當于對父類的主動使用),不過直接通過子類引用父類元素,不會引起子類的初始化(參見示例6) * Java虛擬機被標明為啟動類的類(包含main方法的) ### Bootstrap CLassloder 由C++編寫的,它本身是虛擬機的一部分,所以它并不是一個JAVA類,也就是無法在java代碼中獲取它的引用 JVM啟動時通過Bootstrap類加載器加載rt.jar等核心jar包中的class文件,之前的int.class,String.class都是由它加載 Bootstrap沒有父加載器,但是它卻可以作為任何一個ClassLoader的父加載器。比如ExtClassLoader 這句話的理解,必須結合后文中的 loadClass()過程,也就是在雙親委托模型中向上迭代父加載器查找時,如果父加載器為null,則jvm內置的加載器去替代,也就是Bootstrap ClassLoader ### Extention ClassLoader 加載目錄%JRE\_HOME%\\lib\\ext目錄下的jar包和class文件。 ### AppClassLoader 加載當前應用的classpath的所有類 java虛擬機的入口應用,sun.misc.Launcher ## 雙親委托 ### loadClass的實現 (向下一直找緩存,向上找實現) 1. 一個AppClassLoader查找資源時,先看看緩存是否有,緩存有從緩存中獲取,否則委托給父加載器。 2. 遞歸,重復第1步的操作。 3. 如果ExtClassLoader也沒有加載過,則由Bootstrap ClassLoader出面。 4. Bootstrap ClassLoader首先查找緩存,如果沒有找到的話,就去找自己的規定的路徑下,也就是sun.mic.boot.class下面的路徑。找到就返回,沒有找到,讓子加載器自己去找 5. Bootstrap ClassLoader如果沒有查找成功,則ExtClassLoader自己在java.ext.dirs路徑中去查找,查找成功就返回,查找不成功,再向下讓子加載器找 6. ExtClassLoader查找不成功,AppClassLoader就自己查找,在java.class.path路徑下查找。找到就返回。如果沒有找到就讓子類找 7. 如果沒有子類會拋出各種異常 ### 為什么要使用這種雙親委托模式呢? * 【重復】因為這樣可以避免重復加載,當父親已經加載了該類的時候,就沒有必要子ClassLoader再加載一次。 * 【安全】考慮到安全因素,我們試想一下,如果不使用這種委托模式,那我們就可以隨時使用自定義的String.class來動態替代java核心api中定義類型,這樣會存在非常大的安全隱患,而雙親委托的方式,就可以避免這種情況,因為String.class已經在啟動時被加載,所以用戶自定義類是無法加載一個自定義的ClassLoade 自定義一個ClassLoader,默認加載路徑為D:\\lib下的jar包和資源 ### NoClassDefFoundError和ClassNotFoundExceptiom NoClassDefFoundError:當java源文件已編譯成.class文件,但是ClassLoader在運行期間在其搜尋路徑load某個類時,沒有找到.class文件則報這個錯 ClassNotFoundException:試圖通過一個String變量來創建一個Class類時不成功則拋出這個異常
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看