13

JDK 1.6 のソースでは、 Collections クラスの swap メソッドは次のように記述されています。

public static void swap(List<?> list, int i, int j) {
    final List l = list;
    l.set(i, l.set(j, l.get(i)));
}

渡されたリストの最終コピーを作成する理由は何ですか? 渡されたリストを直接変更しないのはなぜですか? この場合、raw タイプの警告も表示されます。

4

1 に答える 1

19

リストのコピーはなく、リストへの参照のコピーのみがあります。最後のキーワードは重要ではありません。ただし、生の型を使用することが重要です。代わりにパラメーターを使用すると、コンパイラーはエラーを報告します。

public static void swap(List<?> list, int i, int j) {
    // ERROR: The method set(int, capture#3-of ?) in the type List<capture#3-of ?>
    // is not applicable for the arguments (int, capture#4-of ?)
    list.set(i, list.set(j, list.get(i)));
}

これは、ジェネリックの欠点を回避し、エラー メッセージを取り除くために、中間変数を使用していることを意味します。

興味深い質問は、なぜジェネリック メソッドを使用しないのかということです。次のコードが機能します。

public static <T> void swap(List<T> list, int i, int j) {
    list.set(i, list.set(j, list.get(i)));
}

答えは、生の型でメソッドを呼び出す古いコードで、このメソッドが警告を生成することです。

List list = ...;
// WARNING: Type safety: Unchecked invocation swap2(List, int, int)
// of the generic method swap2(List<T>, int, int) of type Swap
Collections.swap(list, 0, 1);
于 2012-05-28T17:29:26.707 に答える