タイプ消去へようこそ。実行時に、ソースコードに含まれてClass<T>いたものが - JVM に消去され、などはすべて同じように見えます。これはチェックされていないキャストの意味です-開発者は自分の責任でそれを行います。代わりに、型消去プロセス中にコンパイラによって挿入されたキャストで、後で発生する可能性があります。ジェネリックに型指定された参照が許可されるべきではないオブジェクトを指しているこの状態は、ヒープ汚染として知られています。ClassClass<Integer>Class<String>ClassCastExceptionClassCastException
OMG - 型引数を強制するより良い方法はありますか?
いいえ、これはジェネリック型の安全性に関して Java が提供できる最高のものです。実際にはオプトインです。多くの IDE では、警告の代わりにこれらのコンパイラ エラーを生成することを提案していますが、怠惰なコードや不正なコードは、チェックされていないキャストを自由に実行したり、未加工の型を使用したりできます(これにより、触れたものすべてに暗黙のチェックされていないキャストがもたらされます)。
補足として、チェックされていないキャストが有効な場合もあります。たとえば、Joshua Bloch の効果的な Java 項目 27、「ジェネリック メソッドを優先する」を実装する場合などです。
private static final Comparator<Object> HASH_CODE_COMPARATOR =
new Comparator<Object>() {
@Override
public int compare(final Object o1, final Object o2) {
return Integer.compare(o1.hashCode(), o2.hashCode());
}
};
public static <T> Comparator<T> hashCodeComparator() {
@SuppressWarnings("unchecked") // this is safe for any T
final Comparator<T> withNarrowedType =
(Comparator<T>)(Comparator<?>)HASH_CODE_COMPARATOR;
return withNarrowedType;
}
ここでは、 が反変的HASH_CODE_COMPARATORに動作するため、チェックされていないキャストは安全です。これはステートレスであり、任意の に対して機能するため、呼び出し元にジェネリック型を決定させることができます。Object
Comparator<String> c = hashCodeComparator();
この場合@SuppressWarnings("unchecked")、未チェックの警告を削除するために使用でき、基本的にコンパイラに信頼するように伝えます。説明のコメントを追加することもお勧めします。