2017-01-17 4 views
0

私のアプリケーションが拡張されるスーパークラスに新しいフックメソッドを導入した依存関係と、アプリケーションの互換性を確保する必要があります。新しく追加されたメソッドを導入する簡単なアプローチ(宣言されたメソッドのサブタイプである戻り値タイプを定義し始めた直後に、私がビルドして使用する古いバージョンでは無視される)は機能しなくなりました。オーバーライドされたJavaメソッドが存在するにもかかわらず呼び出されない

オーバーライドされたメソッドを直接foo.bar("")と呼び出すと、スーパークラスメソッドが呼び出されます。ただし、デバッガーfoo.getClass().getMethod("bar", String.class).invoke(foo, "")からのリフレクションを通じて呼び出すと、オーバーライドされたメソッドが期待通りに呼び出されます。戻り値の型がオーバーライドされた同じ型に絞り込まれると、このメソッドは正しく呼び出されます。戻り値は以前はサブタイプでした。

答えて

2

covariant return typesとオーバーライドの場合には、Javaコンパイラは、その宣言の対応と同様の効果を有するが、オーバーライドされたメソッドの戻り型を有するブリッジ方法を生成します。これは、JVMが名前、引数リスト、およびJavaプログラミング言語とは異なり戻り値の型でメソッドを識別するために必要です。コンパイラは、メソッドがオーバーライドされ、返された型がスーパークラスのメソッドによって返された型のサブタイプであることを認識している場合にのみ、これを行います。 (決定は@Override注釈に依存しないことに注意してください)。

この場合、コンパイラは、新しく追加されたメソッドがオーバーライドであることを認識しません(古いバージョンの依存性はそれをまったく宣言しないため、共変量の戻り型を知る方法はありません)。その結果、JVMがオーバーライドとして識別し、継承ツリーをさらに上にメソッド実装を探し出すブリッジメソッドは生成されません。

これを回避するにはいくつかの方法があります。

  • 互換性の前方この方法を確実にオーバーライド方法は両親と同じ戻り値の型を持っていることを確認してください。したがって、ブリッジメソッドは必要ありません。
  • 依存関係の新バージョンに対してビルドし、との互換性を確保するために作業します。と互換性があります。ここで最も顕著な欠点は、サポートされている最小限のバージョンが、例えば、maven POMによって宣言されたバージョンではないことです。
  • バイトコード操作を使用して、ブリッジメソッドを明示的に生成します。私は読者にそうしてもらうためにここにリンクを張っていません。
関連する問題