Effective Java—Generic(2)
10391 ワード
[アイテム28]配列ではなくリストを使用します。
最初の配列は「共変」(共変)です.例えば、
Sub
がSuper
のサブタイプである場合、アレイSub[]
はアレイSuper[]
のサブタイプである.これを公変と呼ぶ.つまり一緒に変わる.逆にジュネーブは変わらない.
List<Sub>
は、List<Super>
の下位タイプでも上位タイプでもない.単純な比較ではジェニーリックに問題があると考えられていますが、実際に問題があるのは配列です.StringタイプをLongタイプのリポジトリに入れることはできません.次のコードに示すように、配列はコードの実行時にのみエラーを表示しますが、リストではコンパイル時にエラーを確認できます.
Object[] objectArray = new Long[1];
// ArrayStoreException 발생
objectArray[0] = "Kimtaeng";
// 아예 컴파일 오류
List<Object> objectList = new ArrayList<Long>();
objectList.add("Kimtaeng");
配列は公変的に存在し、ジェニーリックは非公変的に存在する.E, List<E>, List<String>
のようなタイプを非実体化タイプ(non-reflable type)と呼ぶ.静音は実体化されていないため、コンパイル時よりも実行時に情報のタイプが少ない.アレイに変換する場合、ネストされたアレイの生成エラーが発生したり、「非チェック変換」の警告が発生したりした場合、アレイE[]ではなくコレクションリスト(List)を使用して解決できることが多い.
public class Chooser {
private final Object[] choiceArray;
public Chooser(Collection choices) {
this.choiceArray = choices.toArray();
}
// 이 메서드를 사용하는 곳에서는 매번 형변환이 필요하다.
// 형변환 오류의 가능성이 있다.
public Object choose() {
Random rnd = ThreadLocalRandom.current();
return choiceArray[rnd.nextInt(choiceArray.length)];
}
}
上記のコードはGenericを使用して次のように変更できます.public class Chooser<T> {
private final T[] choiceArray;
public Chooser(Collection<T> choices) {
// 오류 발생 incompatible types: java.lang.Object[] cannot be converted to T[]
this.choiceArray = choices.toArray();
}
// choose 메소드는 동일하다.
}
次の図に示すように、コードを変更すると互換性のないタイプのエラーが解決されます.// Object 배열을 T 배열로 형변환하면 된다.
this.choiceArray = (T[]) choices.toArray();
コンパイルエラーは消えますが、Unchecked Cast警告が表示されます.タイプパラメータTがどのようなタイプなのか分からないため、運転時においても変換が安全であることは保証されない.ジェニーリックは実行時にタイプ情報をクリアするので、どんなタイプなのか分かりません.Unchecked Castなどのチェックされていない変換警告を削除するには、配列ではなくリストを使用します.class Chooser<T> {
private final List<T> choiceList;
public Chooser(Collection<T> choices) {
this.choiceList = new ArrayList<>(choices);
}
public T choose() {
Random rnd = ThreadLocalRandom.current();
return choiceList.get(rnd.nextInt(choiceList.size()));
}
}
整理すると、配列は公共で実体化され、ジェニーリックは不公正で、タイプ情報が消去されます.したがって、配列は実行時にタイプが安全であり、コンパイル時には安全ではありません.ジュネーブはその道に逆らって行った.Reference
この問題について(Effective Java—Generic(2)), 我々は、より多くの情報をここで見つけました https://velog.io/@roo333/Effective-Java-제네릭1-2ph74troテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol