下面的代码在Eclipse编译时没有任何错误,但是在Javac中生成了一个错误。似乎是编译器错误,但我不知道哪一个是正确的。
我想指出的是,我知道如何通过更改代码以使其同时适用于此错误来纠正此错误,但这不是当前主题。我只想知道是Java还是Eclipse问题。
我尝试使用Intellij,但遇到相同的javac错误。
重现此错误的示例代码:
import java.util.ArrayList;
import java.util.List;
public class A<T extends B> {
protected List<C> list = new ArrayList<>();
class C {}
public void createIO() {
A<? extends B> x = null;
List<A<? extends B>.C> y = x.list;
}
}
class B {
}
JVM:
openjdk version "13-BellSoft" 2019-09-17
OpenJDK Runtime Environment (build 13-BellSoft+33)
OpenJDK 64-Bit Server VM (build 13-BellSoft+33, mixed mode, sharing)
使用Eclipse,我没有任何错误。使用Javac,我有error:
A.java:13: error: incompatible types: List<A<CAP#1>.C> cannot be converted to List<A<? extends B>.C>
List<A<? extends B>.C> y = x.list;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends B from capture of ? extends B
这看起来像是[javac
的错误,因为这两种类型都兼容:两者都引用了C
的内部类A
,并带有B
的通用参数或扩展了[ C0]。
B
替换为? extends B
来简化代码(或者,如果您不仅要使用列表元素使用B
来替换B
-specif,还希望使用T
来替换T
-specific东西),也可以用javac
编译而没有问题。请注意,集合Collection<Foo>
可以包含Foo
类型的元素以及扩展了Foo
类型的元素。public void createIO() {
A<B> x = null;
List<A<B>.C> y = x.list;
}
这里是another example where the Eclipse Java compiler and javac
differ。
编译器知道javac
的参数类型必须是List
的实例化:
C
并且A<? extends B>.C> ^
的参数类型必须是A
的子类型,但是它仍然不确切地知道哪个实例化。长话短说,
B
,您可以按以下步骤修复代码: