面試被問到為什么
非靜態(tài)內(nèi)部類為什么會持有外部類的引用
,一時語塞,只知道有這么回事,但是沒有具體去調(diào)研,這次就簡單的分析下。
分析
- 先做個簡單的類
// InnerClassReference.java
public class InnerClassReference {
private InnerClass clazz = new InnerClass();
private class InnerClass {
}
}
- 用
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
來訪問外部類的成員變量。