面试被问到为什么
非静态内部类为什么会持有外部类的引用
,一时语塞,只知道有这么回事,但是没有具体去调研,这次就简单的分析下。
分析
- 先做个简单的类
// InnerClassReference.java
public class InnerClassReference {
private InnerClass clazz = new InnerClass();
private class InnerClass {
}
}
- 用
javac
编译成*.class
文件看一下效果,这里有2个类
这是IDE自带的decompiler,语法是不符合java规范的,能看出个大概
// 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中,构造方法在编译的时候添加了一个参数,这个参数就是外部类的实例!
所以“非静态内部类为什么会持有外部类的引用”是发生在编译阶段!
举一反三
同理,内部类可以访问外部类的成员变量也是这个道理,可以理解为通过this$0
来访问外部类的成员变量。
网友评论