我希望跟随单元测试失败并使用 ClassCastException ,但是它的传递。
该类有一个泛型方法,其第二个参数和返回值的类型为V。
在第二次调用方法时,使用第二个参数V的类型作为Integer,返回类型应为Integer。但在运行时它实际上返回String值。
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class GenericMethodTest {
private class NonGenericClass {
private final Map<Object, Object> myMap = new HashMap<>();
<K, V> V addGeneric(K key, V value) {
V existingV = (V) myMap.get(key);
// why no ClassCastException on this above line, when type of V is Integer, but myMap.get(key) returns value of
// type String?
if (existingV == null) {
myMap.put(key, value);
return value;
}
return existingV;
}
}
@Test
public void test() {
NonGenericClass nonGenericClass = new NonGenericClass();
nonGenericClass.addGeneric("One", "One");
// String valueString = (String) nonGenericClass.addGeneric("One", Integer.valueOf(1));
// Compiler error as expected, if above line uncommented - Cannot cast from Integer to String.
// But no error at run-time, and below call returns value of type String.
nonGenericClass.addGeneric("One", Integer.valueOf(1));
}
}
答案 0 :(得分:1)
这是由于类型擦除。基本上,K
和V
的类型在执行时是未知的。未选中对V
的强制转换 - 您应该在编译时收到警告(可能建议您使用-Xlint
进行编译)。
如果您希望在执行时检查演员表,则需要相关的Class
对象,此时您可以使用Class.cast
进行检查。
有关详情,请参阅type erasure in the Java generics FAQ以及"Can I cast to a parameterized type?"。