假设我有一个方法
@SuppressWarnings("unchecked")
public <T extends Number> T getNumber() {
try {
return (T)number;
} catch (ClassCastException e) {
return null;
}
}
假设number
是Integer
的实例,请调用类似
Float f = getNumber();
结果为ClassCastException
。
我知道(不知何故)这是因为类型擦除,但有人可以提供更深刻的解释,为什么异常升级到分配级别并且不能在方法内捕获?
注意:我确实有版本public <T extends Number> T getNumber(Class<T> classT)
来检查classT中的类型,但希望摆脱传递classT
并停止想知道上述问题。< / p>
答案 0 :(得分:5)
在类型擦除后,return (T)number
变为return (Number)number
(因为Number
是T
的类型绑定),它不会抛出异常(因为number
}是Integer
)的实例。
另一方面,作业
Float f = getNumber();
编译为
Float f = (Float) getNumber();
,因为getNumber()
会返回Number
,但如果没有强制转换,则无法将其分配给Float
变量。
当ClassCastException
不是getNumber()
时,此投注会引发Float
。
类型擦除是从类型(可能包括参数化类型和类型变量)到类型(从不参数化类型或类型变量)的映射。我们写| T |对于类型T的擦除。擦除映射定义如下......
类型变量(第4.4节)的擦除是其最左边界的擦除。