0

これがその例です。

class ParentReturnType {}
class ChildReturnType extends ParentReturnType {}
class Parent {
  ParentReturnType foo() {...}
}
class Child<R extends ChildReturnType> extends Parent {
  @Override
  R foo() {...}
}

classChildに対して、javacという名前の 2 つのメソッドを生成しますfoo

  1. 最初は をfoo()返しますChildReturnType。その本体は で定義したものですChild.foo()
  2. 2 番目は をfoo()返しますParentReturnType。これは単純に最初の呼び出しを呼び出しますfoo()

javacの 2 つのバージョンを生成する理由がよくわかりませんfoo()

(ソースコードで) で定義された本体foo()で返される1 つのバージョンで十分だと思います。ParentReturnTypeR foo()

4

1 に答える 1

1

これは、Java 言語とは異なり、JVM にはメソッドの ID の一部として戻り値の型が含まれているためです。

したがって、Java では、戻り値の型によってメソッドをオーバーライドすることはできません (入力引数によってオーバーライドする必要があります)。ただし、JVM の世界では、そうすることは合法です。

ジグソーパズルの最後のピースは、Java が実行時ではなくコンパイル時に呼び出す JVM 署名を識別することです。したがって、これらのメソッドのどれを呼び出す必要があるかを識別するのはコンパイラであり、ジェネリックが Java に追加されたときの設計目標は、ランタイムへの変更を最小限に抑えることでした。つまり、可能な限りコンパイラの段階で行われたため、2 つのメソッドを生成することを含まない他のソリューションを想定することができましたが、ツールが既に利用可能であり、時間スケールを考えると、そうすることは現実的でした。

于 2013-03-06T06:03:52.077 に答える