java - 为什么这里不允许转换为 "GenericType<?>"?

标签 java eclipse generics

此代码会导致 javac 出现编译错误(但值得注意的是,不会出现 Eclipse 4.2.2!):

public interface Foo<T> {
}

class Bar<T> implements Foo<Iterable<T>> {
}

class Test {
    void test(Foo<? extends Iterable<? extends String>> foo) {
        Bar<?> bar = (Bar<?>) foo;
    }
}

javac 的错误是这样的:

Foo.java:9: error: inconvertible types
        Bar<?> bar = (Bar<?>) foo;
                              ^
  required: Bar<?>
  found:    Foo<CAP#1>
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Iterable<? extends String> from capture of ? extends Iterable<? extends String>

将类型转换更改为 (Bar) foo (即使用原始类型)允许代码编译,更改 foo 的类型也是如此简单地 Foo<? extends Iterable<?>> .

编辑:有趣的是,这个简单的更改导致 Eclipse 拒绝,但 javac 接受:

void test(Foo<Iterable<String>> foo) {
    Bar<?> bar = (Bar<?>) foo;
}

而且,Eclipse 和 javac 都拒绝这个:

void test(Foo<Iterable<? extends String>> foo) {
    Bar<?> bar = (Bar<?>) foo;
}

最佳答案

你的代码是合理的,应该编译:你正在缩小静态类型 FooBar同时扩大泛型类型 ? extends Iterable<? extends String>? , 其中顶级 ?是通配符捕获。这是一个经过检查的转换,它应该在没有警告的情况下编译。

你应该 submit an Oracle bug .我试图搜索相应的错误报告,但 this old closed ticket是我能找到的最接近这个问题的(IMO Oracle bug 数据库很难搜索)。有机会我会搜索更多,因为这个 javac 问题感觉很熟悉。

关于java - 为什么这里不允许转换为 "GenericType<?>"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17711180/

相关文章:

generics - Generic 类型的关闭参数 - 异常

.net - VB.NET 实现多种逆变接口(interface)类型

java - Jquery Load 函数不引用母版页脚本文件

java - 如果条件不能正常工作

java - Tomcat 和 HSQL java.lang.ClassNotFoundException : org. hsqldb.jdbcDriver

java - 如何在 Eclipse for OSX 中打开并运行此 Java 项目

带接口(interface)的 C# 泛型

java - Camel 和 Elasticsearch 带屏蔽插件

java - 具有另一个域的 Selenium cookie

java - 如何根据用户输入创建表?