Java:非静态嵌套类和instance.super()
我很难理解Java中的非静态嵌套类。考虑下面的例子,它打印“内”和“子”。p> 我知道内部实例总是必须与外部实例相关联,这也适用于Child,因为它扩展了内部实例。我的问题是Java:非静态嵌套类和instance.super(),java,inner-classes,Java,Inner Classes,我很难理解Java中的非静态嵌套类。考虑下面的例子,它打印“内”和“子”。p> 我知道内部实例总是必须与外部实例相关联,这也适用于Child,因为它扩展了内部实例。我的问题是o.super()语法意味着什么-为什么它调用内部构造函数 我只见过一个普通的super(args)用于调用超类构造函数,而super.method()用于调用被重写方法的超类版本,但从未见过类似于instance.super()的形式,它被称为“限定超类构造函数调用” 引用自: 显式构造函数调用语句可分为两类: 备用构造
o.super()
语法意味着什么-为什么它调用内部构造函数
我只见过一个普通的super(args)
用于调用超类构造函数,而super.method()
用于调用被重写方法的超类版本,但从未见过类似于instance.super()
的形式,它被称为“限定超类构造函数调用”
引用自:
显式构造函数调用语句可分为两类:
- 备用构造函数调用以关键字this开始(可能以显式类型参数开头)。它们用于调用同一类的备用构造函数
- 超类构造函数调用以关键字super(可能以显式类型参数开头)或主表达式开始。它们用于调用直接超类的构造函数。超类构造函数调用可以进一步细分:
- 非限定超类构造函数调用以关键字super开始(可能以显式类型参数开头)
- 限定的超类构造函数调用以主表达式开始。它们允许子类构造函数显式地指定新创建的对象相对于直接超类的直接封闭实例(§8.1.3)。当超类是内部类时,这可能是必需的
class Outer {
static class Inner {
final Outer outer;
Inner(Outer outer) {
this.outer = outer;
System.out.println("Inner");
}
}
}
public class Child extends Outer.Inner {
Child(Outer o) {
super(o); // o.super();
System.out.println("Child");
}
public static void main(String args[]) {
new Child(new Outer());
}
}
看看这个,您应该能够理解o.super()在做什么。从概念上讲,非静态内部类“属于”特定对象。这有点像每个类都有自己的版本,很像一个非静态字段或方法属于一个特定的对象 这就是为什么我们有一些有趣的语法,比如
instance.new internal()
和instance.super()
——用于回答“但是谁的internal
?”这个问题的上下文。(在外部类的非静态方法中,您可以只说new internal()
,通常它是this.new internal()
的缩写)为什么Child
中的o.super()
最终调用outer.internal
构造函数?这很简单:因为子级扩展了Outer.internal
,构造函数调用总是链接到层次结构上
下面是对您的代码片段的轻微扩展,以说明:
class Outer {
Outer() {
System.out.println("Outer");
}
void outerMethod() { }
class Inner {
Inner() {
System.out.println("OuterInner");
outerMethod();
}
String wealth;
}
}
class OuterChild extends Outer {
OuterChild() {
System.out.println("OuterChild");
}
}
public class OuterInnerChild extends Outer.Inner {
OuterInnerChild(Outer o) {
o.super();
System.out.println("OuterInnerChild");
this.wealth = "ONE MILLION DOLLAR!!!";
}
public static void main(String args[]) {
System.out.println(new OuterInnerChild(new Outer()).wealth);
new OuterChild();
}
}
这张照片是:
Outer
OuterInner
OuterInnerChild
ONE MILLION DOLLAR!!!
Outer
OuterChild
一些关键意见:
- 因为
,所以它继承了OuterInnerChild扩展了Outer.Inner
,就像普通的子类语义一样wealth
- 就像正常的子类语义一样,
的构造函数链接到OuterInnerChild
Outer.Inner
- 就像正常的子类语义一样,
- 因为
,所以它的构造函数链,即使没有显式调用OuterChild扩展了Outer
- 无论是隐式还是显式,构造函数都将层次结构链接起来
但是为什么编译器要求
OuterInnerChild
构造函数采用Outer o
,并且调用o.super()
现在这是针对内部类语义的:这样做是为了确保
OuterInnerChild
的所有实例都有一个Outer.inner
实例,该实例是OuterInnerChild
的超类。否则,Outer.internal
的构造函数将不会有一个Outer
的封闭实例来调用outerMethod()
。始终不要忘记基本原则,在调用子类构造函数的过程中,无论内部/外部类如何,总是先实例化父类。在您的场景中,当您扩展内部类时,您的内部类是父类的成员,需要实例化父类,然后调用实际的内部类构造函数。事实上,据我理解,非静态内部类本质上是上述内容的语法糖。不,嵌套的静态类本质上是一个外部级别的类,它只是为了方便打包。我只是说一个非静态的内部类是语法糖之上的语法糖:-DLOL。。。这有什么面试问题
标签?作为Java职位面试的一部分,我被要求完成一个IKM测验;这个问题是测验中一个问题的简化形式。@Kiv你有实际使用的例子吗?
Outer
OuterInner
OuterInnerChild
ONE MILLION DOLLAR!!!
Outer
OuterChild