1

私は最近遭遇しましたなぜJava5+APIは共変リターンタイプを利用しないのですか?

私は質問に同意します。Java5では、JDK開発者はクローンに共変リターン型を使用し、既存のクラスを変更して、次のように記述できた可能性があります。

ArrayList<String> list = new ArrayList<String>();
ArrayList<String> clone = list.clone();

それ以外の

ArrayList<String> clone = (ArrayList<String>)list.clone();

しかし、いくつかの理由で、はそれをしませんでした。

test.ArrayList.cloneリターンタイプをObjectからArrayListに変更して、「以前にコンパイルされたクラスが新しいリターンタイプのメソッドを見つけることができない」かどうかを確認するためにいくつかの実験を行いましたが、問題を再現できませんでした。バイトコードでは、oldへの呼び出しはtest.ArrayList.clone次のようになります

 INVOKEVIRTUAL test.ArrayList.clone()Ljava/lang/Object;

つまり、メソッドのシグネチャにはリターンタイプが含まれているため、変更後、そのシグネチャはに変更されtest.ArrayList.clone()Ltest.ArrayListます。したがって、古いクラスは壊れているように見えますが、実際には、test.ArrayList.classに2つのクローンメソッドがあるため、壊れません。

  public clone()Ltest.ArrayList;
  public bridge clone()Ljava/lang/Object; 

2つ目はブリッジで、共変バージョンを呼び出すだけです。

 ...
 INVOKEVIRTUAL ArrayList.clone()Ltest.ArrayList;
 ...

そのため、古いクラスは問題なく動作し続けます。

クローンのリターンタイプを変更するとバイトコードが壊れることを誰かが説明できますか?

4

1 に答える 1

2

リンクされた質問に対するこの回答には、理由が含まれています。メソッドArrayListを上書きし、戻り型としてclone指定されたすべてのサブクラスが破損します。Object

于 2012-12-24T13:35:43.470 に答える