Java基礎-內部類-為什麼成員內部類可以無條件訪問外部類

來源:互聯網
上載者:User

標籤:

 

 

  在此之前,我們已經討論過了成員內部類可以無條件訪問外部類的成員,那具體究竟是如何?的呢?下面通過反編譯位元組碼檔案看看究竟。事實上,編譯器在進行編譯的時候,會將成員內部類單獨編譯成一個位元組碼檔案,下面是Outter.java的代碼:

public class Outter {    private Inner inner = null;    public Outter() {             }         public Inner getInnerInstance() {        if(inner == null)            inner = new Inner();        return inner;    }          protected class Inner {        public Inner() {                     }    }}

 

  編譯之後,出現了兩個位元組碼檔案:

  反編譯Outter$Inner.class檔案得到下面資訊:

E:\Workspace\Test\bin\com\cxh\test2>javap -v Outter$InnerCompiled from "Outter.java"public class com.cxh.test2.Outter$Inner extends java.lang.Object  SourceFile: "Outter.java"  InnerClass:   #24= #1 of #22; //Inner=class com/cxh/test2/Outter$Inner of class com/cxh/test2/Outter  minor version: 0  major version: 50  Constant pool:const #1 = class        #2;     //  com/cxh/test2/Outter$Innerconst #2 = Asciz        com/cxh/test2/Outter$Inner;const #3 = class        #4;     //  java/lang/Objectconst #4 = Asciz        java/lang/Object;const #5 = Asciz        this$0;const #6 = Asciz        Lcom/cxh/test2/Outter;;const #7 = Asciz        <init>;const #8 = Asciz        (Lcom/cxh/test2/Outter;)V;const #9 = Asciz        Code;const #10 = Field       #1.#11; //  com/cxh/test2/Outter$Inner.this$0:Lcom/cxh/test2/Outter;const #11 = NameAndType #5:#6;//  this$0:Lcom/cxh/test2/Outter;const #12 = Method      #3.#13; //  java/lang/Object."<init>":()Vconst #13 = NameAndType #7:#14;//  "<init>":()Vconst #14 = Asciz       ()V;const #15 = Asciz       LineNumberTable;const #16 = Asciz       LocalVariableTable;const #17 = Asciz       this;const #18 = Asciz       Lcom/cxh/test2/Outter$Inner;;const #19 = Asciz       SourceFile;const #20 = Asciz       Outter.java;const #21 = Asciz       InnerClasses;const #22 = class       #23;    //  com/cxh/test2/Outterconst #23 = Asciz       com/cxh/test2/Outter;const #24 = Asciz       Inner; {final com.cxh.test2.Outter this$0; public com.cxh.test2.Outter$Inner(com.cxh.test2.Outter);  Code:   Stack=2, Locals=2, Args_size=2   0:   aload_0   1:   aload_1   2:   putfield        #10; //Field this$0:Lcom/cxh/test2/Outter;   5:   aload_0   6:   invokespecial   #12; //Method java/lang/Object."<init>":()V   9:   return  LineNumberTable:   line 16: 0   line 18: 9   LocalVariableTable:   Start  Length  Slot  Name   Signature   0      10      0    this       Lcom/cxh/test2/Outter$Inner;  }

  第11行到35行是常量池的內容,下面先看看第38行的內容:

final com.cxh.test2.Outter this$0;

 

  這行是一個指向外部類對象的指標,看到這裡想必大家豁然開朗了。也就是說編譯器會預設為成員內部類添加了一個指向外部類對象的引用,那麼這個引用是如何賦初值的呢?下面接著看內部類的構造器:

public com.cxh.test2.Outter$Inner(com.cxh.test2.Outter);

  從這裡可以看出,雖然我們在定義的內部類的構造器是無參構造器,編譯器還是會預設添加一個參數,該參數的類型為指向外部類對象的一個引用,所以成員內部類中的Outter this&0 指標便指向了外部類對象,因此可以在成員內部類中隨意訪問外部類的成員。從這裡也間接說明了成員內部類是依賴於外部類的,如果沒有建立外部類的對象,則無法對Outter this&0引用進行初始化賦值,也就無法建立成員內部類的對象了。

 

Java基礎-內部類-為什麼成員內部類可以無條件訪問外部類

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.