为什么我不能使用 class 对象访问 java 中的内部静态 class

Why can't I access an inner static class in java with class object

当我访问带有 class 实例的静态成员时它起作用了,那么为什么静态内部 class 出错?
在 C++ 中,我们可以使用实例以及 class 名称访问静态成员。
Java.

有何不同
class OuterClass{
    static public int x;
    public static void show(){
        System.out.println(x);
    }
    public static class InnerClass{
        static public int y;
    }
}

public class MyApp {
    public static void main(String[] args){
        OuterClass obj = new OuterClass();
        obj.x= 5;
        System.out.println(obj.x);   // This runs fine 
        obj.InnerClass.y = 10;       // Error
        System.out.println(obj.InnerClass.y);
        OuterClass.InnerClass.y=10;  // This works why ?
        System.out.println(OuterClass.InnerClass.y);
    }
}

如果这是一个愚蠢的问题,我很抱歉,Java希望你能理解。
此致

obj.x = 5; System.out.println(obj.x);

是的,这行得通,但是 'by accident'。 java 语言规范允许这样做,但请注意 每个 linting 工具,java 当前的核心工程团队将 所有 告诉你这是糟糕的代码风格,你不应该这样做。

在罗马时,要像罗马人一样:如果您更喜欢这种代码风格,那...无关紧要。不要写这个。你不在自己的小泡泡里,你阅读别人写的代码,其他人也会阅读和使用你写的代码。

java 仍然允许这样做的唯一原因是 java 不喜欢破坏向后兼容性。

之所以如此疯狂,是因为 someExpr.someThing 强烈暗示 someExpr 在任何方面或形式上都是相关的。比如,在运行时,someExpr 被求值以及它指向的任何对象(记住,在 java 中,除基元外的所有变量都像 C 指针,但在 java 中我们称它们为references.Potayto Potahto) 然后用于获取该字段或调用该方法。

但那是 而不是 如果 someThing 是一个静态概念会发生什么:对于这个的简单证明,使 someExpr 为空并注意它是如何仍然有效(没有抛出 NullPointerException),因此证明没有发生取消引用。

这令人困惑。如果 someThing 是静态的,那么它属于 class 而不是它的任何特定实例,所以这样写: OuterClass.x.

obj.InnerClass.y = 10; System.out.println(obj.InnerClass.y);

是的,错误。虽然您可以通过编写 x.fieldOrMethod 来引用静态方法和静态字段,其中 x 是一个表达式,其静态(compile-time,而不是运行时)类型是具有 fieldOrMethod 作为字段或方法成员的类型,它有效,但如果它是内部类型则无效。为什么?因为 java 规范是这么说的。

请注意,内部类型是在 java 1.1 中添加的,我很确定 lang 团队已经意识到允许 obj.staticThing 是一个设计错误,因此他们有意决定不扩展并延长那个错误。为什么你应该养成这种风格的习惯,这进一步加剧了火上浇油;它并不总是有效。

OuterClass.InnerClass.y=10; System.out.println(OuterClass.InnerClass.y);

我们终于得到了正确的代码。不仅它有效,而且您应该这样做。 OuterClass.InnerClass InnerClass 的名称:所有 class 都是有效的 'static' 当只引用 class 时:不是那个OuterClass 的每个实例都有一个 InnerClass 变体(即使 InnerClass 是 non-static):概念“InnerClass”只存在一次。只有一个 java.lang.Class<?> 的实例来表示“InnerClass”,不管 InnerClass 是否是静态的。你会提到什么其他方式InnerClassobj.InnerClass 没有任何意义 - 引用 InnerClass 不需要 obj 的实例 - 提供不相关和未使用的信息很奇怪(在这种情况下,obj 引用)。