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

为什么对泛型的这种使用不会引发运行时或编译时异常?

杨建章
2023-03-14
问题内容

我在类中有一个方法,该方法具有通过使用泛型指定的返回类型。

public class SomeMain {

  public static void main(String[] args) {

    Foo<Integer> foo = new Foo<Integer>();
    System.out.println(foo.getFoo()); // Works, prints out "Foo"

  }

  public static class Foo<E>  {
    public E getFoo() {
      return (E) "Foo";
    }
  }
}

对于通用返回类型,我假设以上示例中的返回将计算为:

return (Integer) "Foo";  // Inconvertible types !!!

而是String返回a并正确打印。

如果将调用更改为:我收到编译错误:

String fooString = foo.getFoo(); // Compile error, incompatible types found
System.out.println(fooString);

我缺少什么来帮助我了解这里发生了什么以及为什么原始版本没有导致编译错误。


问题答案:

这是因为重载解析解决了您的println调用println(Object),因为没有println(Integer)

请记住,Java的泛型会在运行时删除。像这样(E) "Foo"的演员阵容将被删除,并移至呼叫站点。有时这不是必需的,因此仅在需要时才将内容转换为正确的类型。

换句话说,在内部不执行任何强制转换getFoo。语言规范支持:

第5.5.2节:已 检查的演员表和未检查的演员表

  • 演员表是完全未经检查的演员表。

对于此类转换,不执行任何运行时操作。

删除后,getFoo返回Object。并将其传递到中println(Object),这完全可以。

如果调用此方法并通过foo.getFoo则会 收到错误消息:

static void f(Integer i) {
    System.out.println(i);
}
// ...
f(foo.getFoo()); // ClassCastException

因为这一次 需要 投射



 类似资料:
  • 我在一个类中有一个方法,该方法具有使用泛型指定的返回类型。 对于通用返回类型,我假设上面示例中的返回将评估为: 相反,被正确返回和打印。 如果我将调用更改为: 我错过了什么,以帮助我理解这里发生了什么,为什么原始版本没有导致编译错误。

  • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用

  • 发生在运行时,因为编译器不能在决定执行哪个函数,但为什么编译器不能在编译时决定呢? 产出: 狗在吃...

  • 例如如下代码: SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date date = sdf.parse("abcd"); 这段代码会抛出ParseException,而它是编译时异常,为什么编译阶段不报错,运行时报错?

  • 我有一个超类动物和两个子类:猫和狗。Dog类有一个专属于它自己的新方法,称为playFetch()。 在运行时,我们知道会发生什么。请说服我为什么编译器不抱怨。还是我的论点正确?

  • 我得到类型不匹配错误,直到我将代码重构为: 返回类型为 此例程末尾的流的类型为 形式类型参数具有以下定义: