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