Liv*_*ivy 14 java generics classcastexception
下面是我写过的第一个Java泛型:
public class MyClass {
public static <T> T castToAnotherType(Object param) {
T ret = null;
try {
ret = (T) param;
} catch (ClassCastException e) {
System.out.print("Exception inside castToAnotherType()");
}
return ret;
}
public static void main(String[] args) {
try {
String obj = MyClass.castToAnotherType(new Object());
} catch (ClassCastException e) {
System.out.print("Exception outside castToAnotherType()");
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果是"castToAnotherType()之外的异常".为什么在泛型方法中不会发生异常?
lex*_*ore 15
T在编译期间被有效擦除.看到这里:
泛型被引入到Java语言中,以便在编译时提供更严格的类型检查并支持泛型编程.为了实现泛型,Java编译器将类型擦除应用于:
- 如果类型参数是无界的,则用泛型或对象替换泛型类型中的所有类型参数.因此,生成的字节码仅包含普通的类,接口和方法.
- 如有必要,插入类型铸件以保持类型安全.生成桥接方法以保留扩展泛型类型中的多态性.
- 类型擦除确保不为参数化类型创建新类; 因此,泛型不会产生运行时开销.
所以你castToAnotherType被T抹去了ca. 下列:
public static Object castToAnotherType(Object param) {
Object ret = null;
try {
ret = (Object) param;
} catch (ClassCastException e) {
System.out.print("Exception inside castToAnotherType()");
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
这显然不会产生任何影响ClassCastException.
main(...) 是一个不同的故事,它产生如下:
public static void main(String[] args) {
try {
String obj = (String) MyClass.castToAnotherType(new Object());
} catch (ClassCastException e) {
System.out.print("Exception outside castToAnotherType()");
}
}
Run Code Online (Sandbox Code Playgroud)
其生产的ClassCastException尝试投放时Object到String.
请参阅Generics教程中的Type Erasure部分.