Java内部类和&继承:这个引用外部是否重复?

时间:2014-10-04 14:30:51

标签: java inheritance language-lawyer inner-classes

考虑具有内部类和继承的这种情况:

class X{
    class A{
       X foo(){
           return X.this; // outer this reference to X returned
       }
    }

}

class Y extends X{
    class B extends A {
       Y foo(){
           return Y.this; // outer this reference to Y returned
       }
    }
}

B的内存布局如何?它是否有两个外部this引用,它们都指向同一个对象?或者它只有一个外this引用。这个参考的类型是什么?

我之所以问:我有一个或多或少的深层次结构,它使用这样的嵌套类。如果为每个继承级别复制了外部this引用,那么我应该考虑一下这个设计。

此外,我只是对Java编程语言的设计细节感到好奇。


我使用javap来检查布局:this指针真的被复制了

class X$A {
  final X this$0; // <-- first reference
  X$A(X);
  X foo();
}

class Y$B extends X$A {
  final Y this$0; // <-- second reference
  Y$B(Y);
  Y foo();
  X foo();
}

2 个答案:

答案 0 :(得分:2)

您可以使用javap查找班级中的哪些字段。 (这取决于编译器,而不是JVM。)在这种情况下:

C:\Users\Jon\Test>javap -p Y$B
Compiled from "Test.java"
class Y$B extends X$A {
  final Y this$0;
  Y$B(Y);
  Y foo();
  X foo();
}

正如您所看到的,有一个对Y的封闭实例的引用 - 但X$A也会引用X的封闭实例(您可以使用javap -p X$A如果你愿意的话)。所以是的,该对象总共有两个字段用于封闭实例。

您可以使用javap -c Y$B查看构造函数的主体,这表明封闭的Y实例引用随后会传递给X.A的构造函数作为封闭{{1}实例引用 - 确认两个字段具有相同的值。

但是,我还没有找到解决JLS的问题。就其本身而言,这是一个值得关注的问题 - 如果你处于一个很难用JLS解释的情况,这是一个很好的暗示,其他开发人员可能无法跟踪正在发生的事情。这对我来说感觉就像一个错综复杂的设计...除非你真的需要所有这些嵌套类,否则我会尽量避免它们。

答案 1 :(得分:1)

我认为继承层次结构中的每个内部类都有它自己的“外部this”引用,因为B可以有一个像

这样的构造函数
    public B(X a) {
        a.super();
    }

这样你就可以了

X x = new X();
Y y = new Y();
Y.B b = y.new B(x);

现在你有一个Y.B的实例,其中foo()方法返回y,但A中的原始foo方法返回x!