列表<列表<>&GT?;和列表<list>是java </list> </list <?>中不兼容的类型

时间:2015-03-14 23:31:16

标签: 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

当涉及到泛型时,似乎java并不认为ListList<?>是相同的类型。

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

上下文

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

编辑:解决方案

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

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

2 个答案:

答案 0 :(得分:1)

好的,这是由于一个微妙的语义差异。

List

这是List的原始类型,相当于T属于Object类型。所以它就像说:

List<Object>

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

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

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

List<?>

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

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

您收到编译时错误!

答案 1 :(得分:-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>>在整个应用中传播?