java中的類是動態加載的,我們先看一下我們常用的類加載方式,先有一個感性的認識,才能進一步

java中的類是動態加載的,我們先看一下我們常用的類加載方式,先有一個感性的認識,才能進一步
深入討論,類加載無非就是下面三種方式。
class A{}
class B{}
class C{}
public class Loader{
    public static void main(String[] args) throws Exception{
       Class aa=A.class;
       Class bb=Class.forName("B");
       Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
    }
}
我們先看.class字面量方式,很多人可能不知道這種方式,因爲這種用法不是一般java語法。
通過javap我們可以發現,這種方式的大致等價於定義了一個靜態成員變量
    static Class class$0;(後面的編號是增長的)
你可以試圖再定義一個  static Class class$0,應該會收到一個編譯錯誤(重複定義)。
Class aa=A.class;
就相當於
    if(class$0==null){
 try{
           Class.forName("A");
 }
 cacth(ClassNotFoundException e){
    throw new NoClassDefFoundError(e);
 }
    }
    Class aa=class$0;
可以很清楚的看到,這種類的字面量定義其實不是加載類的方式,而是被編譯器處理了,實質
上是使用了Class.forName方法,但是使用這種方式有一個很大的好處就是不用處理異常,因爲
編譯器處理的時候如果找不到類會拋出一個NoClassDefFoundError。也許你覺得需要處理
ClassNotFoundException這種異常,事實上99%的情況下我們可以把這種異常認爲是一個錯誤。
所以大部分情況我們使用這種方式會更簡潔。
最常用的方式就是Class.forName方式了,這也是一個通用的上層調用。這個方法有兩個重載,
可能很多人都忽略了第二個方法。
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException
第二個方法後面多了兩個參數,第二個參數表示是否初始化,第三個參數爲指定的類加載器。
在上面的例子中:
Class bb=Class.forName("B");等價於
Class bb=Class.forName("B",true,Loader.class.getClassLoader());
這裏要詳細說一下這個類的初始化這個參數,如果這個參數爲false的話,
類中的static成員不會被初始化,static語句塊也不會被執行。
也就是類雖然被加載了,但是沒有被初始化,不過在第一次使用時仍然會初始化。
所以我們有時候會看到Class.forName("XXX").newInstance()這樣的語句,爲什麼這裏要創建一個
不用的實例呢?不過是爲了保證類被初始化(兼容以前的系統)。
其實第二個方法是比較難用的,需要指定類加載器,如果不指定而且又沒有安裝安全管理器的化,
是無法加載類的,只要看一下具體的實現就明白了。
最本質的方式當然是直接使用ClassLoader加載了,所有的類最終都是通過ClassLoader加載的,
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
這裏通過使用系統類加載器來加載某個類,很直接的方式,但是很遺憾的是通過這種方式加載類,
類是沒有被初始化的(也就是初始化被延遲到真正使用的時候).不過我們也可以借鑑上面的經驗,加載
後實例化一個對象Class cc=ClassLoader.getSystemClassLoader().loadClass("C").newInstance()。
這裏使用了系統類加載器,也是最常用的類加載器,從classpath中尋找要加載的類。
java中默認有三種類加載器:引導類加載器,擴展類加載器,系統類加載器。
java中的類加載有着規範的層次結構,如果我們要了解類加載的過程,需要明確知道哪個類被誰
加載,某個類加載器加載了哪些類等等,就需要深入理解ClassLoader的本質。
以上只是類加載的表面的東西,我們還將討論深層次的東西。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章