Javagenerics中不会抛出ClassCastException
下面是我写过的第一个Javagenerics:
public class MyClass { public static 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()"); } } }
结果是“castToAnotherType()之外的exception” 。 为什么在generics方法中不会发生exception?
编译期间T
被有效擦除。 看到这里 :
generics被引入到Java语言中,以便在编译时提供更严格的类型检查并支持generics编程。 为了实现generics,Java编译器将类型擦除应用于:
- 如果类型参数是无界的,则将generics类型中的所有类型参数替换为其边界或对象。 因此,生成的字节码仅包含普通的类,接口和方法。
- 如有必要,插入类型铸件以保持类型安全。 生成桥接方法以保留扩展generics类型中的多态性。
- 类型擦除确保不为参数化类型创建新类; 因此,generics不会产生运行时开销。
所以你的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; }
哪个显然不会产生任何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()"); } }
在尝试将Object
为String
时会产生ClassCastException
。
请参阅generics教程中的Type Erasure部分。
好吧,既然编译器擦除了generics类型参数,那么方法内部的转换基本上等同于:
Object ret = null; try { ret = (Object) param; } ...
这不是问题,无论你传递给你的方法是什么(因为任何Object都可以转换为Object)。
但是,当您尝试将该Object分配给String时,在main方法中,会发生ClassCastException
,因为Object
无法强制转换为String
。
所有generics类型都在已编译的代码中被擦除。 就编译代码而言, castToAnotherType
只返回一个Object
。 但是,您的main
方法尝试将其分配给String
,并且它不是String
,因此会产生ClassCastException
。
这是因为通用类型擦除,
T ret = null; try { ret = (T) param; ...
由编译器翻译成
Object ret = null; try { ret = (T) param; ...
- Java:未选中从X转换为Y /如何实现castOrNull
- readResolve无法正常工作? :出现了一个Guava的SerializedForm实例
- ClassCastException在Hibernate / Spring 4升级后,无法将Proxy36强制转换为SessionImplementor
- 将HashMap值添加到TreeSet时出错
- ClassCastException将List 转换为Class
- 在进行通用转换时,在generics方法中捕获ClassCastException
- ClassCastException与“无法强制转换”编译错误
- 类Castexception:com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
- Hibernate类强制转换exception