在Java中使用带引用的super()

时间:2016-03-04 10:12:02

标签: java

我有三个班级

class WithInner {
   class Inner {}
}

public class InheritInner extends WithInner.Inner
{ //constructor
InheritInner(WithInner wi) {
    wi.super();
}
}

这个例子取自Eckel的Thinking in Java。我无法理解为什么我们不能调用wi = new WithInner();而不是.super()?在调用wi.super()时我们调用了Object的默认构造函数,不是吗?

1 个答案:

答案 0 :(得分:8)

内部类维护对外部实例的引用(例外是static内部类)。在这种情况下,WithInner.Inner实例具有对包含WithInner实例的引用。在实例化内部类时创建此关联。

如果没有对外部类的引用,则无法创建内部类的实例。扩展这样的内部类的类也具有这样的引用,并且需要委托给内部类构造函数以建立关联。执行此操作的语法如示例所示:

wi.super();

这里,super()本质上是指超类构造函数 - 即WithInner.Inner构造函数。构造函数没有正式获取参数,但它仍然需要对外部实例(类型WithInner)的引用。整个行本质上意味着"调用超类构造函数,并与wi实例关联#34;。

与具有显式关联的内部类的实例化语法进行比较:

wi.new WithInner.Inner()

是的,这也是有效的语法。但是,它在野外并不常见(因为内部类实例通常只是从外部类中创建,并且在这种情况下,关联是隐含的 - 在这种情况下,对此没有必要语法,它明确提供关联。)

具体参考您的问题:

  

我无法理解为什么我们无法调用wi = new WithInner();而不是.super()?

这不会将创建的WithInner实例与内部类实例相关联。您得到编译时错误,因为您的InheritInner构造函数不再显式调用合成超类构造函数,并且无法隐式调用它,因为它需要外部实例关联的参考。将外部实例引用视为内部类构造函数的隐藏参数(实际上,它是如何在引擎盖下实现的)可能是最容易的。

  

在调用wi.super()时我们调用的是Object的默认构造函数,不是吗?

不,您正在调用WithInner.Inner构造函数,该构造函数具有"隐藏"外部实例引用的参数; wi基本上作为隐藏参数值传递给WithInner.Inner构造函数。