List <List <?>>和List <List>是java中不兼容的类型

Oli*_*dža 9 java generics casting raw-types unbounded-wildcard

我没有得到这个代码编译的方式:

List<List> a = new ArrayList();
List<List<?>> b = new ArrayList();

a = b; // incompatible types
b = a; // incompatible types
Run Code Online (Sandbox Code Playgroud)

似乎java 在泛型方面不考虑List并且List<?>是相同的类型.

这是为什么?还有一些不错的出路吗?

上下文

有一个带有以下签名的库函数:public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type).这适用于作为参数传递的简单类型,但在泛型的情况下,结果不会使用通配符进行参数化,从而导致javac抱怨原始类型.我想将结果传播到我的应用程序的其余部分,Set<Class<? extends GenericTypeHere<?>>>但是简单的转换不能像我期望的那样工作.

编辑:解决方案

感谢您的回答,以下是我最终的工作方式:

@SuppressWarnings({"rawtypes", "unchecked"})
private static Set<Class<? extends GenericTypeHere<?>>> factoryTypes() {
    return (Set) new Reflections("...").getSubTypesOf(GenericTypeHere.class);
}
Run Code Online (Sandbox Code Playgroud)

chr*_*her 2

好的,这是由于细微的语义差异造成的。

List
Run Code Online (Sandbox Code Playgroud)

这是 的原始类型List,相当于T类型的存在Object。所以这等于说:

List<Object>
Run Code Online (Sandbox Code Playgroud)

现在,编译器知道一个事实,无论发生什么,这是 type 的子类Object。如果你这样做..

List myList = new ArrayList();
myList.add(new Object());
Run Code Online (Sandbox Code Playgroud)

它会工作得很好!这是因为Object是相同的或者是该类型的某种派生。

List<?>
Run Code Online (Sandbox Code Playgroud)

这实际上是一个未知的列表Java 文档)。我们甚至不知道这里的东西的子类是 type Object。事实上,该?类型本身就是一种未知类型。与它无关Object!这就是为什么当你尝试做的时候..

List<?> myList = new ArrayList<?>();
myList.add(new Object());
Run Code Online (Sandbox Code Playgroud)

你会得到一个编译时错误!

  • 说“List”与说“List&lt;Object&gt;”*不*相同——但您不是本页上第一个提出这一主张的人。这种误解从何而来?我觉得很奇怪。 (3认同)