Java:非静态嵌套类和instance.super()
我很难理解 Java 中的非静态嵌套类。考虑以下示例,它先打印“Inner”,然后打印“Child”。
class Outer {
class Inner {
Inner() { System.out.println("Inner"); }
}
}
public class Child extends Outer.Inner {
Child(Outer o) {
o.super();
System.out.println("Child");
}
public static void main(String args[]) {
new Child(new Outer());
}
}
我知道 Inner 的实例始终必须与 Outer 实例关联,这也适用于 Child,因为它扩展了 Inner。我的问题是 o.super()
语法的含义是什么 - 为什么它调用内部构造函数?
我只见过一个简单的 super(args)
用于调用超类构造函数和 super.method()
用于调用重写方法的超类版本,但从未见过形式为instance.super()
。
I'm having a hard time wrapping my head around non-static nested classes in Java. Consider the following example, which prints "Inner" and then "Child".
class Outer {
class Inner {
Inner() { System.out.println("Inner"); }
}
}
public class Child extends Outer.Inner {
Child(Outer o) {
o.super();
System.out.println("Child");
}
public static void main(String args[]) {
new Child(new Outer());
}
}
I understand that instances of Inner always have to be associated with an Outer instance, and that that applies to Child too since it extends Inner. My question is what the o.super()
syntax means - why does it call the Inner constructor?
I've only seen a plain super(args)
used to call the superclass constructor and super.method()
to call the superclass version of an overridden method, but never something of the form instance.super()
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这称为“合格的超类构造函数调用”。
引用自此处 :
It's called a "qualified superclass constructor invocation".
Citing from here:
内部类(非静态子类)本质上是嵌套类(静态子类),具有返回其父对象的隐式链接。这是上面的代码,使用静态嵌套类编写:
看看这个,您应该能够理解 o.super() 在做什么。
Inner Classes (non-static child classes) are essentially Nested Classes (static child classes) with implicit links back to their parent objects. Here is your above code, written instead using a static nested class:
Looking at this, you should be able to understand what o.super() was doing.
为什么
Child
中的o.super()
最终会调用Outer.Inner
构造函数?这很简单:因为Child 扩展了 Outer.Inner
,并且构造函数调用始终在层次结构中链接起来。下面是对您的代码片段的稍微扩展以进行说明:
这将打印:
一些关键观察结果:
OuterInnerChild 扩展了 Outer.Inner
,所以它继承了wealth
,就像正常的子类语义一样OuterInnerChild
的构造函数链接到Outer.Inner
的构造函数OuterChild 扩展了 Outer
,其构造函数链,即使没有显式调用现在这是特定于内部类语义的:这样做是为了确保
OuterInnerChild
的所有实例都有一个Outer.Inner
的封闭Outer
实例,OuterInnerChild
的超类。否则,Outer.Inner
的构造函数将不会有一个Outer
的封闭实例来调用outerMethod()
。Why does
o.super()
inChild
ends up invokingOuter.Inner
constructor? It's simple: becauseChild extends Outer.Inner
, and constructor calls are always chained up the hierarchy.Here's a slight expansion to your snippet to illustrate:
This prints:
Some key observations:
OuterInnerChild extends Outer.Inner
, it inheritswealth
, just like normal subclass semanticsOuterInnerChild
chains to the constructor ofOuter.Inner
OuterChild extends Outer
, its constructor chains, even when not invoked explicitlyNow that is specific to inner class semantics: it's done to ensure that all instances of
OuterInnerChild
has an enclosingOuter
instance forOuter.Inner
, the super class ofOuterInnerChild
. Otherwise, the constructor ofOuter.Inner
would not have an enclosing instance ofOuter
to invokeouterMethod()
on.从概念上讲,非静态内部类“属于”特定对象。这有点像每个类都有自己的版本,就像非静态字段或方法属于特定对象一样。
这就是为什么我们有有趣的语法,如
instance.new Inner()
和instance.super()
- 对于问题的答案“but whose<”的上下文/em>内部
?”并不是立即显而易见的。 (在外部类的非静态方法中,您可以只说new Inner()
,并且像往常一样,它是this.new Inner()
的缩写。)Conceptually, a non-static inner class “belongs” to a particular object. It's sorta like each one gets its own version of the class, much like a non-static field or method belongs to a particular object.
So that's why we have funny syntax like
instance.new Inner()
andinstance.super()
— for contexts where the answer to the question “but whoseInner
?” isn't immediately obvious. (In a non-static method of the outer class, you can just saynew Inner()
, and as usual that's short forthis.new Inner()
.)永远不要忘记基本原则,在调用子类构造函数的过程中,无论内部/外部类如何,总是首先实例化父类。在您的场景中,当您扩展内部类并且您的内部类是父类的成员时,需要实例化然后调用实际的内部类构造函数。
Always not to forget basic principles, in process of calling a sub class constructor it's always the parent class is instantiated first irrespective of inner/outer classes. In your scenario, as you are extending inner class and your inner class is a member of parent class which needs to be instantiated then followed by calling the actual inner class constructor.