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

以下是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());
    }
}

根据该示例的讨论,运行main()的输出将是“Goodnight,Dick”.这是因为静态方法是根据调用它们的变量/表达式的静态类型调用的.

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

最佳答案
事实上,这里的s.greeting()等同于Super.greeting(),因为s被定义为Super,而静态方法不关心类实例.你肯定知道他们是全班同学.因此从类实例调用静态方法是没有意义的.当然,实例s是您指定的Sub(),因此调用非静态方法Sub.name().

Java official tutorials开始:

You can also refer to static fields with an object reference like

myBike.numberOfBicycles

but this is discouraged because it does not make it clear that they
are class variables.

允许静态方法类实例的只会使代码更不易读,更晦涩难以调试而不真正添加任何有用的功能.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...