未经检查的强制转换涉及通配符类型

时间:2015-09-15 18:38:17

标签: java generics intellij-idea

有人可以解释为什么这是一个未经检查的演员

static void foo(Collection<? extends Number> collection) {
    List<? extends Number> list = (List<? extends Number>) collection;
}

但这不是<?p?

static void bar(List<? extends Number> list) {
    Collection<? extends Number> collection = (Collection<? extends Number>) list;
}

我认为它与捕获有关,但我想要一个明确的解释。

修改

我意识到这是一个措辞严厉的问题,正确的答案是&#34;因为List扩展了Collection&#34;。然而,在IntelliJ中,它会产生一个警告,当你投射到更具体的类型时,你通常不会得到警告。从下面的评论看来,这可能只是IntelliJ中的一个错误。确切的警告在下面的评论中(由于某种原因,我不能在这里重现它)。我没有收到以下任何一个警告

static void foo(Collection<Number> collection) {
    List<Number> list = (List<Number>) collection;
}

static <T> void foo(Collection<T> collection) {
    List<T> list = (List<T>) collection;
}

static void foo(Collection<?> collection) {
    List<?> list = (List<?>) collection;
}

1 个答案:

答案 0 :(得分:0)

因为从List<? extends Number>List<? extends Number>的转换是向下转换,并且通常需要在运行时检查对象的类型。但是,如果类型参数实际上是扩展Number的类,则运行时环境无法检查。该信息在运行时不可用,Java Generics(&#34;类型参数&#34;)仅存在于静态Java类型系统中,它们不会影响编译的代码。因此,如果CollectionList,则可以在运行时检查强制转换的唯一内容。

另一种情况是简单的向上转换,其中不需要运行时信息。您可以在编译时检查此强制转换是否始终有效。因此,缺乏关于运行时类型参数的信息是无关紧要的。