多级静态嵌套 class 产生错误输出
Multilevel static nested class producing wrong output
当下面的代码是 运行 时,它会打印 "X.Q"
而不是语言规范要求的 "A<T>.X.Q"
。
class A<T> {
static class X {
static class Q {
public static void main() {
System.out.println("A<T>.X.Q");
}
}
}
}
class B extends A<B.Y.Q> {
static class Y extends X {
} // X here is inherited from A
}
class X {
static class Q {
public static void main() {
System.out.println("X.Q");
}
}
}
public class Test {
public static void main(String[] args) {
B.Y.Q.main();
}
}
谁能帮我理解这个程序的输出是什么,根据我的理解应该是 "A<T>.X.Q"
而不是 "X.Q"
,如果我在某些地方弄错了请纠正我
Q 的主要方法,打印 X.Q 是被调用的方法,因为 B.Y 扩展了 X(而不是 A.X),其 Q 方法隐藏了 A.X.Q。主要方法。
后续有点乱,简单的添加trace或者一步步调试就可以看到完整的调用树。
好的,让我们看看你有什么。根据我的理解,你的论点基本上是关于 Y extends X
但 X
。默认情况下访问外部范围。如果删除外部 X
,它将无法编译,因为 X
不可用。对于内部静态 classes,您必须在扩展时放置显式导入语句或使用完全限定名称引用它。
这是分辨率中的默认约定。这也有意义 如果你意识到在外部范围内只能有 1 个 class 具有相同的名称但是你可以有许多内部静态 class 具有相同的名称。 你需要一个约定来访问所有这些。此约定以 看似 直观的方式解决了它(否则,您必须在扩展时为所有 X
键入完全限定名称)
如果你考虑外面的,它应该打印,"X.Q"
它确实如此。
您得到 "X.Q"
打印的原因是 X
指的是未命名包的 class X
范围,而不是 A<T>.X
。 "outside" X
在 B
之后被声明为 并不重要,因为 Java 编译器在解析 B.Y
的基地class.
您可以在代码中强制继承 A.X
,如下所示:
class B extends A<B.Y.Q> {
static class Y extends A.X {
} // ^^
// Add this
}
编辑:(感谢 user695022 的评论)
奇怪的是,如果外部 class 不是通用的,问题就会消失:
class A {
static class X {
static class Q {
public static void main() {
System.out.println("A<T>.X.Q");
}
}
}
}
当下面的代码是 运行 时,它会打印 "X.Q"
而不是语言规范要求的 "A<T>.X.Q"
。
class A<T> {
static class X {
static class Q {
public static void main() {
System.out.println("A<T>.X.Q");
}
}
}
}
class B extends A<B.Y.Q> {
static class Y extends X {
} // X here is inherited from A
}
class X {
static class Q {
public static void main() {
System.out.println("X.Q");
}
}
}
public class Test {
public static void main(String[] args) {
B.Y.Q.main();
}
}
谁能帮我理解这个程序的输出是什么,根据我的理解应该是 "A<T>.X.Q"
而不是 "X.Q"
,如果我在某些地方弄错了请纠正我
Q 的主要方法,打印 X.Q 是被调用的方法,因为 B.Y 扩展了 X(而不是 A.X),其 Q 方法隐藏了 A.X.Q。主要方法。
后续有点乱,简单的添加trace或者一步步调试就可以看到完整的调用树。
好的,让我们看看你有什么。根据我的理解,你的论点基本上是关于 Y extends X
但 X
。默认情况下访问外部范围。如果删除外部 X
,它将无法编译,因为 X
不可用。对于内部静态 classes,您必须在扩展时放置显式导入语句或使用完全限定名称引用它。
这是分辨率中的默认约定。这也有意义 如果你意识到在外部范围内只能有 1 个 class 具有相同的名称但是你可以有许多内部静态 class 具有相同的名称。 你需要一个约定来访问所有这些。此约定以 看似 直观的方式解决了它(否则,您必须在扩展时为所有 X
键入完全限定名称)
如果你考虑外面的,它应该打印,"X.Q"
它确实如此。
您得到 "X.Q"
打印的原因是 X
指的是未命名包的 class X
范围,而不是 A<T>.X
。 "outside" X
在 B
之后被声明为 并不重要,因为 Java 编译器在解析 B.Y
的基地class.
您可以在代码中强制继承 A.X
,如下所示:
class B extends A<B.Y.Q> {
static class Y extends A.X {
} // ^^
// Add this
}
编辑:(感谢 user695022 的评论)
奇怪的是,如果外部 class 不是通用的,问题就会消失:
class A {
static class X {
static class Q {
public static void main() {
System.out.println("A<T>.X.Q");
}
}
}
}