为什么使用泛型不会抛出运行时或编译时异常? [英] Why does this use of Generics not throw a runtime or compile time exception?

查看:206
本文介绍了为什么使用泛型不会抛出运行时或编译时异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got a method in a class that has a return type specified by use of a generic.

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";
    }
  }
}

使用通用返回类型,我假设上面例子中的返回值将评估为:

With the generic return type, I assumed the return in the above example would evaluate to:

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

而是返回 String 并正确打印。

Instead a String is returned and printed correctly.

如果我将通话更改为以下内容,我会收到编译错误:

I get a compilation error if I change the call to be:

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

我错过了什么来帮助我理解这里发生的事情以及为什么原始版本没有结果编译错误。

What am I missing to help me understand what's going on here and why the original version didn't result in a compilation error.

推荐答案

这是因为重载决议解析了你的 println 调用 println(Object),因为没有 println(整数)

This is because overload resolution resolved your println call to println(Object), since there is no println(Integer).

请记住,Java的泛型在运行时会被删除。并删除像(E)Foo这样的强制转换,并将其移至呼叫网站。有时这不是必需的,所以只有在需要时才会将事物转换为正确的类型。

Keep in mind that Java's generics are erased at runtime. And casts like (E) "Foo" are removed, and are moved to call site. Sometimes this is not necessary, so things are casted to the right type only when needed.

换句话说,在$ code> getFoo 。语言规范支持这一点:

In other words, no casts are performed inside getFoo. The language spec supports this:


第5.5.2节已检查的强制转换和未经检查的强制转换


  • 演员阵容是完全未选中的演员。

  • The cast is a completely unchecked cast.

没有执行任何运行时操作这样一个演员。

No run-time action is performed for such a cast.

擦除后, getFoo 返回对象。这会被传递到 println(Object),这很好。

After erasure, getFoo returns Object. And that gets passed into println(Object), which is perfectly fine.

如果我调用此方法并通过 foo.getFoo ,我收到错误:

If I call this method and pass foo.getFoo, I will get an error:

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

因为这次需要进行投标。

这篇关于为什么使用泛型不会抛出运行时或编译时异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆