当前位置: 首页 > 面试题库 >

执行泛型转换时,在泛型方法中捕获ClassCastException

夏侯渊
2023-03-14
问题内容

假设我有一个方法

@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并且不再怀疑上面的问题。


问题答案:

在类型擦除之后,return (T)number变为return (Number)number(因为Number是的类型边界T),不会引发异常(因为number是的实例Integer)。

另一方面,分配

Float f = getNumber();

编译为

Float f = (Float) getNumber();

由于会getNumber()传回Number,如果没有强制转换,就无法将其指派给Float变数。

此转换抛出ClassCastExceptionwhen getNumber()不是Float

4.6。类型擦除

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

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



 类似资料:
  • 假设我有一个方法 假设是的实例,调用方法如 结果转换为。 我知道(不知何故)这是因为类型擦除,但有人能提供更深刻的解释为什么异常升级到赋值级别并且在方法内部不可捕捉吗? 注意:我确实有<code>public版本

  • 问题内容: 我正在与一起工作,并且在更换单元格工厂时需要通过一个 我所在的班级是A,但我不知道如何使用“捕获”? 我试图创造 但IDEA显示警告 我尝试使用特定的类(例如String)代替“?” 同样,但没有任何帮助。 谁能向我解释如何使用此方法? 谢谢。 编辑: 我收集了一点点信息。该的应该是,但是,TreeTableColumn是我与原始类型创建工作(在库)。 使用原始类型回叫有效。但是还有其

  • 我想说得具体一点。我有一个名为Result的类和一个名为Result的派生类 这些类在方法中用作返回类型。为此,我创建了这个helper类: 正如您所看到的,上面的代码对于成功有两种返回类型,一种是如果您不想返回任何东西,另一种是如果您想返回一些东西,但是失败的结果永远不会返回什么东西。这是不必要的,只是一个错误消息。这使我想到以下问题:当我想创建一个可以使用返回类型返回Success,而不使用返

  • 安吉丽卡·兰格(Angelica Langer)在关于仿制药的常见问题解答中说(参见Technicalities.FAQ822): 如果这些方法具有具有不同边界的类型参数,则它们不会重写,因为这些方法的签名不是重写等价的。请记住,类型参数边界是泛型方法签名的一部分。 示例(泛型子类型方法重载泛型超类型方法;不推荐): 我不明白为什么方法在类中重载。据我所知,这应该是一个编译时错误,因为在和中具有相

  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符

  • 如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个