隨筆 - 63  文章 - 0  trackbacks - 0
          <2009年4月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          內(nèi)部類:定義在其他類里面的類。
          使用內(nèi)部類的理由:
          1.內(nèi)部類方法能夠訪問外部類的任何數(shù)據(jù)成員包括私有成員。
          2.對同一個包的其他類,內(nèi)部類是不可見的。
          3.匿名內(nèi)部類能夠方便的定義回調(diào)而不用寫太多方法。

          非靜態(tài)內(nèi)部類沒有默認的構(gòu)造函數(shù),非靜態(tài)內(nèi)部類的構(gòu)造函數(shù)都有一個外圍類對象的引用。
          內(nèi)部類的特殊語法規(guī)則:
          1.相對內(nèi)部類,引用其外部類隱式對象的形式:OuterClass.this
          2.調(diào)用內(nèi)部類的構(gòu)造函數(shù):outerObject.new InnerClass(construction parameters);
          3.外部類外面引用內(nèi)部類:OuterClass.InnerClass

          內(nèi)部類是一種編譯器現(xiàn)象與虛擬機無關(guān)。編譯器將內(nèi)部類翻譯為用$分隔外部類名和內(nèi)部類名的常規(guī)類文件,虛擬機對此并無所知。
          使用javap -private OuterClass$InnerClass。javap這個工具確實挺不錯的,對分析字節(jié)碼和源碼都有很大的幫助。
          可以看出詳細的內(nèi)部類源碼清單,其中包括了編譯器自動添加的部分:
          public class Outer
          {
           public class Inner
           {
           }
          }
          當內(nèi)部類是非靜態(tài)內(nèi)部類時相應(yīng)的內(nèi)部類的詳細源碼如下:
          Compiled from "Outer.java"
          public class Outer$Inner extends java.lang.Object{
              final Outer this$0;  //編譯器自動在內(nèi)部類里面添加了指向外部類對象的引用
              public Outer$Inner(Outer);  //內(nèi)部類的構(gòu)造函數(shù)默認有一個外部類對象作為參數(shù)。
          }

          當內(nèi)部類是靜態(tài)內(nèi)部類時:
          Compiled from "Outer.java"
          public class Outer$Inner extends java.lang.Object{
              public Outer$Inner(); //沒有了對外部類對象的引用
          }


          如下代碼模擬了上面內(nèi)部類的情形唯一不同的是這里的Inner沒有訪問Outer私有數(shù)據(jù)的權(quán)限:
          class Outer{
             Inner in = new Inner(this);
          }

          class Inner{
             public Inner(Outer outer){
                this.outer = outer;
             }
            
             private Outer outer;
          }

           

          //那么權(quán)限是如何控制的呢?當內(nèi)部類中的方法訪問到外部類的私有數(shù)據(jù)時(注意如果內(nèi)部類沒有方法去訪問外部類的私有數(shù)據(jù)不會生成該靜態(tài)方法static int access$000(Outer);)
          public class Outer
          {
           private int i;
           public void methodOne()
           {
           }

           class Inner
           {
            public void print(){
             System.out.println(Outer.this.i);
            }
           }
          }

          相應(yīng)的外部類詳細源碼如下:
          public class Outer
          {
             public Outer();

             public void methodOne();
             static int access$000(Outer); //由編譯器合成的用于內(nèi)部類對外部類進行特殊訪問權(quán)限的控制:這也是
                                          //為什么內(nèi)部類能夠訪問外部類中的私有數(shù)據(jù)的原因。
             private int i;
          }

          內(nèi)部類訪問外部類的private數(shù)據(jù)的這種方式很可能導致危險,雖然access$000不是一個合法的Java方法名,但是熟悉class文件結(jié)構(gòu)的黑客可以使用十六進制編輯器輕松創(chuàng)建一個用虛擬機指令調(diào)用那個方法的類文件。由于隱秘的訪問方法需要擁有包可見性,所以攻擊代碼需要與被攻擊類放在同一個包中??傊?,如果內(nèi)部類訪問了外部類的私有數(shù)據(jù)域,就有可能通過附加在外部類所在包中的其他類訪問私有數(shù)據(jù)。

          局部內(nèi)部類:定義在方法之中,因此局部類沒有public和private修飾符。對外界是完全隱藏的。
          局部類不僅能夠訪問外部類,還能訪問方法中的局部變量(或方法的參數(shù))。不過那些局部變量要聲明為final的。


          匿名內(nèi)部類:用外部類+$+數(shù)字的形式表示。一個外部類中有多個匿名內(nèi)部類時,其生成的class文件對應(yīng)有Outer$(1、2、3)的形式表示。注意到該匿名內(nèi)部類是final的。
          final class Outer$1
          {
             Outer$1(Outer);

             public void method();

             final Outer this$0;
          }

          嵌套類:當內(nèi)部類不需要訪問外部類的數(shù)據(jù)成員時應(yīng)該使用嵌套類。注意只有內(nèi)部類可以聲明為static的其他不行。
          在接口中聲明的內(nèi)部類自動轉(zhuǎn)換為public static的,在接口中定義的成員自動都是public static的。

          內(nèi)部類構(gòu)造函數(shù)的可見性與其類的可見性相同。

           

          posted on 2009-04-16 14:06 lanxin1020 閱讀(150) 評論(0)  編輯  收藏 所屬分類: j2se
          主站蜘蛛池模板: 益阳市| 道真| 额敏县| 攀枝花市| 洞头县| 桑植县| 文昌市| 文登市| 怀远县| 广德县| 休宁县| 阿鲁科尔沁旗| 静宁县| 惠水县| 卢湾区| 赤水市| 土默特右旗| 芷江| 鹿邑县| 静海县| 浠水县| 固原市| 杨浦区| 当涂县| 汝城县| 花垣县| 达州市| 巴里| 新民市| 利川市| 县级市| 甘肃省| 宝兴县| 新邵县| 竹溪县| 瓦房店市| 股票| 灵武市| 宿州市| 伊吾县| 滕州市|