在进行通用转换时,在泛型方法中捕获ClassCastException

pir*_*rho 2 java generics casting type-erasure classcastexception

假设我有一个方法

@SuppressWarnings("unchecked")
public <T extends Number> T getNumber() {
   try {
      return (T)number; 
   } catch (ClassCastException e) {
      return null;
   }
}
Run Code Online (Sandbox Code Playgroud)

假设number是一个实例Integer,调用类似的方法

Float f = getNumber();
Run Code Online (Sandbox Code Playgroud)

结果成了一个ClassCastException.

我知道(不知何故)这是因为类型擦除,但有人可以提供更深刻的解释为什么异常升级到赋值级别并且不能在方法内捕获?

注意:我确实有public <T extends Number> T getNumber(Class<T> classT)从classT检查类型的版本,但希望摆脱传递classT并停止想知道上述问题.

Era*_*ran 5

在类型擦除之后,return (T)number变为return (Number)number(因为Number是类型绑定T),它不会抛出异常(因为它number是一个实例Integer).

另一方面,任务

Float f = getNumber();
Run Code Online (Sandbox Code Playgroud)

被编译为

Float f = (Float) getNumber();
Run Code Online (Sandbox Code Playgroud)

因为getNumber()返回a Number,不能在没有强制转换的Float情况下分配给变量.

这个演员抛出的ClassCastException时候getNumber()不是Float.

4.6.类型擦除

类型擦除是从类型(可能包括参数化类型和类型变量)到类型(从不参数化类型或类型变量)的映射.我们写| T | 对于T类的擦除,擦除映射定义如下......

类型变量(第4.4节)的擦除是其最左边界的擦除.