9

无论哪种方式,我都没有得到这段代码来编译:

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

a = b; // incompatible types
b = a; // incompatible types

在泛型方面,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);
}
4

2 回答 2

2

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

List

这是 的 原始类型List,等同于T类型Object。所以这和说的一样:

List<Object>

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

List myList = new ArrayList();
myList.add(new Object());

它会正常工作的!这是因为Object是相同的,或者是类型的某种派生。

List<?>

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

List<?> myList = new ArrayList<?>();
myList.add(new Object());

你得到一个编译时错误!

于 2015-03-14T23:43:59.107 回答
-2
    List<? extends List> a = new ArrayList();
    List<? extends List<?>> b = new ArrayList();
    a = b;

作品

Set<Class<? extends GenericTypeHere<?>>>

将暗示 Set<Class<YourClass extends AnotherClass<YourClass>>> 如上述通配符答案中所述

是什么阻止你使用

Set<Class<YourClass extends AnotherClass>>在整个应用程序中传播?

于 2015-03-14T23:35:56.040 回答