此代码会导致 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;
}
最佳答案
你的代码是合理的,应该编译:你正在缩小静态类型 Foo
至 Bar
同时扩大泛型类型 ? 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/