隨筆 - 1, 文章 - 4, 評論 - 0, 引用 - 0
          數(shù)據(jù)加載中……

          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 aa=A.class;
          就相當(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方式了,這也是一個通用的上層調(diào)用。這個方法有兩個重載,
          可能很多人都忽略了第二個方法。
          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)就明白了。
          最本質(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ì)。
          以上只是類加載的表面的東西,我們還將討論深層次的東西。

          原文:http://dev.csdn.net/author/treeroot/a481eb323af84caab1149221432e46b9.html

          posted on 2007-01-25 14:00 lurker 閱讀(81) 評論(0)  編輯  收藏 所屬分類: 工作日志


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 剑河县| 巍山| 宁南县| 博野县| 安国市| 射阳县| 五指山市| 达拉特旗| 滕州市| 罗定市| 阳新县| 来安县| 七台河市| 信丰县| 通化县| 宜君县| 文昌市| 上虞市| 吉水县| 波密县| 沁阳市| 浦东新区| 延川县| 宜春市| 攀枝花市| 宁城县| 来凤县| 富阳市| 昭觉县| 新闻| 方山县| 海安县| 明溪县| 始兴县| 绿春县| 河源市| 河南省| 新乡市| 巴彦县| 彭水| 贞丰县|