<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 類的加載器 ![](https://img.kancloud.cn/d6/80/d6802bf1f9bf054a13cdd9dd0eb6957f_695x309.png) ![](https://box.kancloud.cn/739586cc003ac9577d30fb19953db921_766x268.png) ![](https://box.kancloud.cn/d5e8943aa8a830d490c4082f37335eab_823x294.png) 當程序要使用某個類時,如果該類還未被加載到內存中,則系統會通過加載,鏈接,初始化三步來實現對這個類進行初始化。 * **加載** 就是指將class文件讀入內存,并為之創建一個Class對象。 任何類被使用時系統都會建立一個Class對象. 通過類的全限定名獲取二進制字節流,將二進制字節流轉換成方法區中的運行時數據結構,在內存中生成Java.lang.class對象; <br> * **鏈接** 執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的; 校驗:檢查導入類或接口的二進制數據的正確性;(文件格式驗證,元數據驗證,字節碼驗證,符號引用驗證) 準備:給類的靜態變量分配并初始化存儲空間; 解析:將常量池中的符號引用轉成直接引用; <br> * **初始化** 激活類的靜態變量的初始化Java代碼和靜態Java代碼塊,并初始化程序員設置的變量值 # 類的初始化時機 1. 創建類的實例 2. 類的靜態變量,或者為靜態變量賦值 3. 類的靜態方法 4. 使用反射方式來強制創建某個類或接口對應的java.lang.Class對象 5. 初始化某個類的子類 6. 直接使用java.exe命令來運行某個主類 # 類加載器的組成 * Bootstrap ClassLoader 根類加載器 也被稱為引導類加載器,負責Java核心類的加載 比如System,String等。在JDK中JRE的lib目錄下rt.jar文件中 * Extension ClassLoader 擴展類加載器 負責JRE的擴展目錄中jar包的加載。 在JDK中JRE的lib目錄下ext目錄 * System ClassLoader 系統類加載器 負責在JVM啟動時加載來自java命令的class文件,以及classpath環境變量所指定的jar包和類路徑 # 類加載器的種類 類加載器有三種,不同類加載器加載不同的 ![](https://box.kancloud.cn/a155ccf73f778db3d3536d30841fd8bf_623x267.png) 1. BootStrap:引導類加載器:加載都是最基礎的文件 2. ExtClassLoader:擴展類加載器:加載都是基礎的文件 3. AppClassLoader:應用類加載器:三方jar包和自己編寫java文件 怎么獲得類加載器? ~~~ ClassLoader 字節碼對象.getClassLoader(); ~~~ ~~~ //獲取系統類加載器 ClassLoader classLoader1 = ClassLoader.getSystemClassLoader(); System.out.println(classLoader1); //獲取擴展類加載器 ClassLoader classLoader2 = classLoader1.getParent(); System.out.println(classLoader2); //獲取引導類加載器(獲取不到) ClassLoader classLoader3 = classLoader2.getParent(); System.out.println(classLoader3); //說明:用戶自定義類是由系統類加載器加載的 ClassLoader loader1 = Person.class.getClassLoader(); System.out.println(loader1); //說明:java 核心api是由引導類加載器加載的 ClassLoader loader2 = Class.forName("java.lang.String").getClassLoader(); System.out.println(loader2); ~~~ # 分析類的加載 Java在需要使用類的時候,才會將類加載,Java的類加載是由類加載器來完成的。 當在命令行模式下執行java XXX.class指令后,java運行程序會嘗試找到JRE安裝的所在目錄,然后尋找jvm.dll(默認是在JRE目錄下bin\client目錄中),接著啟動JVM并進行初始化動作,產生Bootstrap Loader,Bootstrap Loader會加載Extended Loader,并設定Extende Loader的parent為Bootstrap Loader。 接著Bootstrap Loader會加載System Loader,并將System Loader的parent設定為Extended Loader。 Bootstrap Loader通常由C編寫而成,Extended Loader是由Java編寫而成,實際是對應于sun.misc.Launcher$ExtClassLoader(Launcher中的內部類).System Loader是由java編寫而成,實際對你關于 sun.misc.Launcher$AppClassLoader(Launcher中的內部類)。 Bootstrap Loader會搜索系統參數sun.boot.class.path中指定位置的類,默認是JRE所在目錄的classes下的.class文件,或lib目錄下.jar文件中(如tr.jar)的類并加載。 可用System.getProperty(“sun.boot.class.path”)來顯示sun.boot.class.path中指定的路徑。 Extended Loader是由Java編寫而成,會搜索系統參數java.ext.dirs中指定位置的類,默認是JRE目錄下的lib\ext\classes目錄下的.class文件,或lib\ext目錄下的.jar文件中的類并加載。 System Loader是由java編寫而成,會搜索系統參數java.class.path中指定位置的類,也就是Classpath所指定的路徑,默認是當前工作路徑下的.class文件。 在加載類時,每個類加載器會先將加載類的任務交給其parent,如果parent找不到,再由自己負責加載。所以在加載類順序為:`Bootstrap Loader——》Extended Loader——》System Loader`的順序來尋找類,若都找不到,會拋出NoClassDefFoundError. 類加載器在Java中是以java.lang.ClassLoader類型存在,每一個類被加載后,都會有一個Class的實例來代表,而每個Class的實例都會記得自己是由哪個ClassLoader加載的。 可以由Class的getClassLoader()取得加載該類的ClassLoader,而從ClassLoader的getParent()方法可以取得自己的parent # 分析 Class.forName()和ClassLoader.loadClass ## Class.forName Class.forName(className)方法,內部實際調用的方法是Class.forName(className,true,classloader); 第2個boolean參數表示類是否需要初始化,Class.forName(className)默認是需要初始化。 一旦初始化,就會觸發目標對象的 static塊代碼執行,static參數也也會被再次初始化。 ## ClassLoader.loadClass ClassLoader.loadClass(className)方法,內部實際調用的方法ClassLoader.loadClass(className,false); 第2個boolean參數,表示目標對象是否進行鏈接,false表示不進行鏈接,由上面介紹可以, 不進行鏈接意味著不進行包括初始化等一些列步驟,那么靜態塊和靜態對象就不會得到執行 # 數據庫鏈接為什么使用Class.forName(className) JDBC Driver源碼如下,因此使用Class.forName(classname)才能在反射回去類的時候執行static塊 ~~~ static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } ~~~ # 加載指定目錄下的配置文件 ~~~ //獲得Demo字節碼文件的類加載器 Class clazz = Demo.class;//獲得Demo的字節碼對象 ClassLoader classLoader = clazz.getClassLoader();//獲得類加載器 //getResource的參數路徑相對classes(src) //獲得classes(src)下的任何的資源 String path = classLoader.getResource("com/wdsa/classloader/jdbc.properties").getPath(); //classLoader.getResourceAsStream(""); System.out.println(path); ~~~
                  <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>

                              哎呀哎呀视频在线观看