【问题标题】:Unchecked cast involving wildcard types涉及通配符类型的未经检查的强制转换
【发布时间】:2015-09-15 18:38:17
【问题描述】:

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

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

但这不是?

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

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

编辑

我意识到这是一个措辞不当的问题,正确答案是“因为List 扩展了Collection”。然而,在 IntelliJ 中,它会生成一个警告,在转换为更具体的类型时通常不会得到该警告。从下面的 cmets 看来,这可能只是 IntelliJ 中的一个错误。确切的警告在下面的 cmets 中(由于某种原因,我无法在此处复制它)。我没有收到以下任何警告

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

【问题讨论】:

  • 是什么让你认为它没有被检查?如果你用-Xlint:unchecked 编译它,你不会收到任何关于未经检查的强制转换的警告。
  • 啊,那可能就是 IntelliJ 了。确切的消息是Unchecked cast: 'java.util.Collection&lt;capture&lt;? extends java.lang.Number&gt;&gt;' to 'java.util.List&lt;? extends java.lang.Number&gt;'
  • 对于从ObjectString 的演员表,它不会给你同样的效果?
  • 没有。当我删除通配符时,它也不会给我同样的结果。

标签: java generics intellij-idea


【解决方案1】:

因为从List&lt;? extends Number&gt;List&lt;? extends Number&gt; 的转换是向下转换,通常需要在运行时检查对象的类型。但是,运行时环境无法检查类型参数是否真的是扩展Number 的类。该信息在运行时不可用,Java 泛型(“类型参数”)仅存在于静态 Java 类型系统中,它们不会影响已编译的代码。因此,唯一可以在运行时检查的演员表是,如果CollectionList

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多