5

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

例の説明によると、running の出力はmain()"Goodnight, Dick" になります。これは、静的メソッドが呼び出される変数/式の静的型に基づいて呼び出されるためです。

これが私の質問です。適度にフローに敏感なコンパイラでもs、呼び出し時に格納されているオブジェクトの型は常に でなければならないことを理解できますSub。したがって、コンパイラがその情報を使用できる場合、静的メソッドを呼び出しても、いくつかのダイナミックバインディングの感触。これが許可されないのはなぜですか?Javaには、すべてのコンパイラがまったく同じように動作するバイトコードを生成するという明確な目標がありますか、それとも他の理由がありますか?

4

2 に答える 2

1

それはあまりJava固有ではありません。次のような「インテリジェントな」コンパイルを想像してくださいs.getClass().greeting()

class A extends Sub {
    static String greeting() { return "Allo"; }
}
class B extends Sub {
    static String greeting() { return "Brrr"; }
}
Super s = condition? new A() : new B();
assert s.greeting.equals(Sub.greeting()); // If compiler cannot infer condition.

コンパイラは複数のソースでそれを行うべきですか? ソースコードが利用できない可能性があるライブラリの外。

むしろ、Javaの誤謬s.greeting()は許されていると思います。

静的継承の用途がないため、そのような機能を発明しない方がよいでしょう。

于 2012-07-12T20:54:20.010 に答える