多级静态嵌套 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 XX。默认情况下访问外部范围。如果删除外部 X,它将无法编译,因为 X 不可用。对于内部静态 classes,您必须在扩展时放置显式导入语句或使用完全限定名称引用它。

这是分辨率中的默认约定。这也有意义 如果你意识到在外部范围内只能有 1 个 class 具有相同的名称但是你可以有许多内部静态 class 具有相同的名称。 你需要一个约定来访问所有这些。此约定以 看似 直观的方式解决了它(否则,您必须在扩展时为所有 X 键入完全限定名称)

如果你考虑外面的,它应该打印,"X.Q"它确实如此。

您得到 "X.Q" 打印的原因是 X 指的是未命名包的 class X 范围,而不是 A<T>.X。 "outside" XB 之后被声明为 并不重要,因为 Java 编译器在解析 B.Y的基地class.

您可以在代码中强制继承 A.X,如下所示:

class B extends A<B.Y.Q> {
    static class Y extends A.X {
    } //                   ^^
      //                Add this
}

Demo 1.

编辑:(感谢 user695022 的评论)

奇怪的是,如果外部 class 不是通用的,问题就会消失:

class A {
    static class X {
        static class Q {
            public static void main() {
                System.out.println("A<T>.X.Q");
            }
        }
    }
}

Demo 2.