ジェネリック型パラメーターは、型が eraseであるため、実行時に回復できません (一部の特殊なケースを除く) 。これは、実行時に と の両方Vector<Integer>
がVector<String>
単なるVector
s であり、それらの要素が単なるObject
参照であることを意味します。
個々の要素の実際のランタイムクラス(instanceof
指摘したようにチェックで検出可能)のみが要素タイプの概念を作成します。そうでない場合、ベクター自体は要素タイプが何であるかわかりません。
したがって、基本的に、任意の型の空のベクトルは、他の型の空のベクトルと同じです。次のようにキャストしても安全です。
Vector<String> noStrings = (Vector<String>) new Vector<Integers>();
ただし、1 つの問題があります。空のベクターは必要な要素の型に準拠していると言えますが、このステートメントは、ベクターが empty のままである限り有効です。これを行う場合:
Vector<Integer> ints = new Vector<Integer>(); // empty
Vector<String> strings = (Vector<String>) ints; // unchecked warning, but still possibly ok
ints.add(1); // here comes trouble
String s = strings.get(1); // oh oh, ClassCastException
編集:
2 番目の質問に答えるには: いいえ、次のように書くことはできません。
public <T> boolean checkType(Vector<T> vec) {
return T instanceof Integer; // impossible
return T == Integer; // impossible
return T.class == Integer.class // impossible
return vec instanceof (Vector<Integer>); // impossible
}
ただし、入力パラメーターとしてクラス トークンを使用するメソッドを作成できます。
static <T> boolean checkElementType(Collection<?> collection, Class<T> elementType) {
for (Object object : collection) {
if (!elementType.isAssignableFrom(object.getClass())) {
return false;
}
}
return true;
}
そして、次のように使用できます。
List<?> list1 = Arrays.asList(1, 2, 3);
List<?> list2 = Arrays.asList(1, 2, 3, "a");
System.out.println(checkElementType(list1, Integer.class)); // true
System.out.println(checkElementType(list2, Integer.class)); // false