隨筆 - 154  文章 - 60  trackbacks - 0
          <2007年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          聲明:

          該blog是為了收集資料,認識朋友,學習、提高技術,所以本blog的內容除非聲明,否則一律為轉載!!

          感謝那些公開自己技術成果的高人們!!!

          支持開源,尊重他人的勞動!!

          常用鏈接

          留言簿(3)

          隨筆分類(148)

          隨筆檔案(143)

          收藏夾(2)

          其他

          學習(技術)

          觀察思考(非技術)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          也是無意間找到的,以前從沒仔細想過底層的問題,看后才發現要學得太多太多,學習!學習!再學習!
           

             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的本質。
              以上只是類加載的表面的東西,我們還將討論深層次的東西。

          posted on 2007-09-25 11:05 lk 閱讀(144) 評論(0)  編輯  收藏 所屬分類: j2se
          主站蜘蛛池模板: 衡阳县| 涞水县| 蓬莱市| 红河县| 武山县| 隆德县| 华容县| 额尔古纳市| 曲阳县| 兴宁市| 阳高县| 南康市| 嘉峪关市| 扎鲁特旗| 雷州市| 昭平县| 江津市| 饶平县| 阳春市| 兰溪市| 望江县| 忻州市| 托克逊县| 沙河市| 北辰区| 古浪县| 正安县| 清镇市| 宝清县| 柯坪县| 衡阳市| 中西区| 福安市| 舟曲县| 大洼县| 明光市| 宣恩县| 凤翔县| 手机| 镇宁| 江西省|