内部类对象如何驻留在内存中?
Outer outer = new Outer();
在堆上创建Outer
类的Object
,并且引用变量指向它。
如果我在写作时就明白了
Outer.Inner inner=outer.new Inner();
Inner
类的对象是在堆上创建的, inner
点是在它上面创建的。 在堆中,我们有两个独立的对象,它们包含自己的实例变量。
但是如果我写的话
Outer.Inner inner=new Outer().new Inner();
还有两个Object
将在堆上创建一个用于Outer
,另一个用于Inner
。 但是参考inner
只有Inner
Object's
成员是可访问的。 谁在堆上引用外部Object
? 如果它没有被任何引用引用,那么它应该有资格进行垃圾收集,这会影响inner
的使用。
内部类包含对其外部类实例的隐藏引用。 如果没有其他引用,那么隐藏引用会使外部类实例保持活动状态。
要查看此操作,请获取此源代码并进行编译:
public class Outer { public class Inner { } }
现在使用java类检查工具javap
来查看隐藏的引用:
$ javap -p Outer\$Inner Compiled from "Outer.java" public class Outer$Inner { final Outer this$0; public Outer$Inner(Outer); }
你会看到有一个名为Outer
名为this$0
的包范围隐藏引用 – 这是我上面谈到的引用。
内部类的每个实例都包含对其外部类的实例的引用。 当你在一个内部类的方法中编写Outer.this
时,它就是你得到的引用。 匿名Outer
实例将不符合垃圾收集的条件,除非与其关联的所有Inner
实例也有资格进行垃圾收集。
当然,内部强调了它想要强引用的东西的强引用 – 就像它的另一半实例变量一样,它们位于Outer中。