類加載器

轉自:rainlife

<script type="text/javascript"></script> 看了王森的《JAVA深度歷險》,做了一個簡單的學習筆記。
1. JAVA類裝載器在裝載類的時候是按需加載的,只有當一個類要使用(使用new 關鍵字來實例化一個類)的時候,類加載器纔會加載這    個類並初始化。
    類Main:
   

java 代碼
 
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.         A a = new A();  
  4.         a.print();  
  5.         B b = new B();  
  6.         b.print();  
  7.     }  
  8. }  

  
  類A:

java 代碼
 
  1. public class A  {  
  2.     public void print() {  
  3.         System.out.println("Using Class A");  
  4.     }  
  5. }  


 類B:

java 代碼
 
  1. public class B {  
  2.     public void print() {  
  3.         System.out.println("Using Class B");  
  4.     }  
  5. }  


執行:java -varbose:class Main
執行結果:
    E:/DEV>java -verbose:class Main
    [Opened C:/Program Files/Java/jre1.5.0_11/lib/rt.jar] (類裝載器會首先加載rt.jar加載基礎類)
    .
    .
    [Loaded Main from file:/E:/DEV/] (類裝載器載入相應類並初始化)
    [Loaded A from file:/E:/DEV/]
    Using Class A
    [Loaded B from file:/E:/DEV/]
    Using Class B
2. 讓JAVA程序具有動態性
   使用顯式方式來實現動態性,我們需要自己動手處理類載入時的細節部分。

     兩種方法:
    |
    +-- 隱式的 : 使用new關鍵字讓類加載器按需求載入所需的類
    |
    +-- 顯式的 :
                     |
                     +-- 由 java.lang.Class的forName()方法加載
                     |
                     +-- 由 java.lang.ClassLoader的loadClass()方法加載

    (1) 使用Class.forName()
    Class.forName()方法具有兩個重載的方法:
            +- public static Class forName(String className)
            |
            +- public static Class forName(String className, boolean initialize,ClassLoader loader)
    參數說明:
        className - 所需類的完全限定名
        initialize - 是否必須初始化類(靜態代碼塊的初始化)
        loader - 用於加載類的類加載器
調用只有一個參數的forName()方法等效於 Class.forName(className, true, loader)。
這兩個方法,最後都要連接到原生方法forName0(),其定義如下:
private static native Class forName0(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException;
只有一個參數的forName()方法,最後調用的是:
forName0(className, true, ClassLoader.getCallerClassLoader());
而三個參數的forName(),最後調用的是:
forName0(name, initialize, loader);
所以,不管使用的是new 來實例化某個類、或是使用只有一個參數的Class.forName()方法,內部都隱含了“載入類 + 運行靜態代碼塊”的步驟。而使用具有三個參數的Class.forName()方法時,如果第二個參數爲false,那麼類加載器只會加載類,而不會初始化靜態代碼塊,只有當實例化這個類的時候,靜態代碼塊纔會被初始化,靜態代碼塊是在類第一次實例化的時候才初始化的。

    (2) 直接使用類加載器
           +— 獲得對象所屬的類 : getClass()方法
           |
           +— 獲得該類的類加載器 : getClassLoader()方法

java 代碼
 
  1. public class Main3 {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Main3 main3 = new Main3();  
  4.         System.out.println("準備載入類");  
  5.         ClassLoader loader = main3.getClass().getClassLoader();  
  6.         Class clazzA = loader.loadClass(args[0]);  
  7.         System.out.println("實例化類A");  
  8.         A o1 = (A) clazzA.newInstance();          
  9.     }  
  10. }  
發佈了34 篇原創文章 · 獲贊 9 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章