Java類加載的表現(xiàn)形式
java中的類是動態(tài)加載的,我們先看一下我們常用的類加載方式,先有一個感性的認識,才能進一步
深入討論,類加載無非就是下面三種方式。
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我們可以發(fā)現(xiàn),這種方式的大致等價于定義了一個靜態(tài)成員變量
??? static Class class$0;(后面的編號是增長的)
你可以試圖再定義一個? static Class class$0,應(yīng)該會收到一個編譯錯誤(重復(fù)定義)。
深入討論,類加載無非就是下面三種方式。
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我們可以發(fā)現(xiàn),這種方式的大致等價于定義了一個靜態(tài)成員變量
??? static Class class$0;(后面的編號是增長的)
你可以試圖再定義一個? static Class class$0,應(yīng)該會收到一個編譯錯誤(重復(fù)定義)。
Class aa=A.class;
就相當(dāng)于
??? if(class$0==null){
?try{
?????????? Class.forName("A");
?}
?cacth(ClassNotFoundException e){
??? throw new NoClassDefFoundError(e);
?}
??? }
??? Class aa=class$0;
就相當(dāng)于
??? if(class$0==null){
?try{
?????????? Class.forName("A");
?}
?cacth(ClassNotFoundException e){
??? throw new NoClassDefFoundError(e);
?}
??? }
??? Class aa=class$0;
可以很清楚的看到,這種類的字面量定義其實不是加載類的方式,而是被編譯器處理了,實質(zhì)
上是使用了Class.forName方法,但是使用這種方式有一個很大的好處就是不用處理異常,因為
編譯器處理的時候如果找不到類會拋出一個NoClassDefFoundError。也許你覺得需要處理
ClassNotFoundException這種異常,事實上99%的情況下我們可以把這種異常認為是一個錯誤。
所以大部分情況我們使用這種方式會更簡潔。
上是使用了Class.forName方法,但是使用這種方式有一個很大的好處就是不用處理異常,因為
編譯器處理的時候如果找不到類會拋出一個NoClassDefFoundError。也許你覺得需要處理
ClassNotFoundException這種異常,事實上99%的情況下我們可以把這種異常認為是一個錯誤。
所以大部分情況我們使用這種方式會更簡潔。
最常用的方式就是Class.forName方式了,這也是一個通用的上層調(diào)用。這個方法有兩個重載,
可能很多人都忽略了第二個方法。
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException
可能很多人都忽略了第二個方法。
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException
第二個方法后面多了兩個參數(shù),第二個參數(shù)表示是否初始化,第三個參數(shù)為指定的類加載器。
在上面的例子中:
Class bb=Class.forName("B");等價于
Class bb=Class.forName("B",true,Loader.class.getClassLoader());
這里要詳細說一下這個類的初始化這個參數(shù),如果這個參數(shù)為false的話,
類中的static成員不會被初始化,static語句塊也不會被執(zhí)行。
也就是類雖然被加載了,但是沒有被初始化,不過在第一次使用時仍然會初始化。
所以我們有時候會看到Class.forName("XXX").newInstance()這樣的語句,為什么這里要創(chuàng)建一個
不用的實例呢?不過是為了保證類被初始化(兼容以前的系統(tǒng))。
其實第二個方法是比較難用的,需要指定類加載器,如果不指定而且又沒有安裝安全管理器的化,
是無法加載類的,只要看一下具體的實現(xiàn)就明白了。
在上面的例子中:
Class bb=Class.forName("B");等價于
Class bb=Class.forName("B",true,Loader.class.getClassLoader());
這里要詳細說一下這個類的初始化這個參數(shù),如果這個參數(shù)為false的話,
類中的static成員不會被初始化,static語句塊也不會被執(zhí)行。
也就是類雖然被加載了,但是沒有被初始化,不過在第一次使用時仍然會初始化。
所以我們有時候會看到Class.forName("XXX").newInstance()這樣的語句,為什么這里要創(chuàng)建一個
不用的實例呢?不過是為了保證類被初始化(兼容以前的系統(tǒng))。
其實第二個方法是比較難用的,需要指定類加載器,如果不指定而且又沒有安裝安全管理器的化,
是無法加載類的,只要看一下具體的實現(xiàn)就明白了。
最本質(zhì)的方式當(dāng)然是直接使用ClassLoader加載了,所有的類最終都是通過ClassLoader加載的,
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
這里通過使用系統(tǒng)類加載器來加載某個類,很直接的方式,但是很遺憾的是通過這種方式加載類,
類是沒有被初始化的(也就是初始化被延遲到真正使用的時候).不過我們也可以借鑒上面的經(jīng)驗,加載
后實例化一個對象Class cc=ClassLoader.getSystemClassLoader().loadClass("C").newInstance()。
這里使用了系統(tǒng)類加載器,也是最常用的類加載器,從classpath中尋找要加載的類。
java中默認有三種類加載器:引導(dǎo)類加載器,擴展類加載器,系統(tǒng)類加載器。
java中的類加載有著規(guī)范的層次結(jié)構(gòu),如果我們要了解類加載的過程,需要明確知道哪個類被誰
加載,某個類加載器加載了哪些類等等,就需要深入理解ClassLoader的本質(zhì)。
以上只是類加載的表面的東西,我們還將討論深層次的東西。
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
這里通過使用系統(tǒng)類加載器來加載某個類,很直接的方式,但是很遺憾的是通過這種方式加載類,
類是沒有被初始化的(也就是初始化被延遲到真正使用的時候).不過我們也可以借鑒上面的經(jīng)驗,加載
后實例化一個對象Class cc=ClassLoader.getSystemClassLoader().loadClass("C").newInstance()。
這里使用了系統(tǒng)類加載器,也是最常用的類加載器,從classpath中尋找要加載的類。
java中默認有三種類加載器:引導(dǎo)類加載器,擴展類加載器,系統(tǒng)類加載器。
java中的類加載有著規(guī)范的層次結(jié)構(gòu),如果我們要了解類加載的過程,需要明確知道哪個類被誰
加載,某個類加載器加載了哪些類等等,就需要深入理解ClassLoader的本質(zhì)。
以上只是類加載的表面的東西,我們還將討論深層次的東西。
原文:http://dev.csdn.net/author/treeroot/a481eb323af84caab1149221432e46b9.html
posted on 2007-01-25 14:00 lurker 閱讀(81) 評論(0) 編輯 收藏 所屬分類: 工作日志