是否允许Java编译器对静态调用具有流敏感性?

Joc*_*hen 5 java jls

以下是JLS第8.4.8.2节的简要示例.

class Super {
    static String greeting() { return "Goodnight"; }
    String name() { return "Richard"; }
}
class Sub extends Super {
    static String greeting() { return "Hello"; }
    String name() { return "Dick"; }
}
class Test {
    public static void main(String[] args) {
        Super s = new Sub();
        System.out.println(s.greeting() + ", " + s.name());
    }
}
Run Code Online (Sandbox Code Playgroud)

根据该例子的讨论,跑步的输出main()将是"晚安,迪克".这是因为静态方法是根据调用它们的变量/表达式的静态类型调用的.

这是我的问题:任何即使是中等流量敏感的编译器都可以确定s在调用时存储的任何对象的类型必须始终如此Sub,因此如果允许编译器使用该信息,即使调用静态方法也可能有一些动态绑定的感觉.为什么不允许这样做?Java是否有明确的目标,即每个编译器生成的行为完全相同的字节码还是有其他原因?

m0s*_*it0 3

实际上这里s.greeting()相当于Super.greeting()因为s被定义为Super并且静态方法不关心类实例。你肯定知道,它们是全班的。因此,从类实例中调用静态方法是没有意义的。当然,实例s是您指定的,因此调用Sub()非静态方法。Sub.name()

来自Java官方教程

您还可以使用对象引用来引用静态字段,例如

myBike.numberOfBicycles

但这是不鼓励的,因为它没有明确表明它们是类变量。

允许静态方法是类实例明智的只会使代码可读性更差,更晦涩难懂并且更难以调试,而不会真正添加任何有用的功能。