非靜態(tài)內(nèi)部類為什么會持有外部類的引用

面試被問到為什么非靜態(tài)內(nèi)部類為什么會持有外部類的引用,一時語塞,只知道有這么回事,但是沒有具體去調(diào)研,這次就簡單的分析下。


分析

  1. 先做個簡單的類
// InnerClassReference.java
public class InnerClassReference {
    private InnerClass clazz = new InnerClass();

    private class InnerClass {
    }
}
  1. javac編譯成*.class文件看一下效果,這里有2個類

這是IDE自帶的decompiler,語法是不符合java規(guī)范的,能看出個大概

// InnerClassReference.class
public class InnerClassReference {
    private InnerClassReference.InnerClass clazz = new InnerClassReference.InnerClass();
    public InnerClassReference() {}
    private class InnerClass {
        private InnerClass() {}
    }
}

// InnerClassReference$InnerClass.class
class InnerClassReference$InnerClass {
    private InnerClassReference$InnerClass(InnerClassReference var1) {
        this.this$0 = var1;
    }
}

可以看到在InnerClass.class中,構(gòu)造方法在編譯的時候添加了一個參數(shù),這個參數(shù)就是外部類的實例!
所以“非靜態(tài)內(nèi)部類為什么會持有外部類的引用”是發(fā)生在編譯階段!

舉一反三

同理,內(nèi)部類可以訪問外部類的成員變量也是這個道理,可以理解為通過this$0來訪問外部類的成員變量。

引用

深入理解Java中為什么內(nèi)部類可以訪問外部類的成員
源碼GitHub(歡迎star,follow)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容