List<List<?>> and List<List> are incompatible types in java [duplicate]

删除回忆录丶 提交于 2019-12-01 00:08:16

问题


I did not get this code to compile either way:

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

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

It seems that java does not consider List and List<?> to be the same type when it comes to generics.

Why is that? And is there some nice way out?

Context

There is a library function with following signature: public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type). This works fine for simple types passed as argument but in case of generics the result is not parametrized with wildcard causing javac to complain about raw type. I would like to propagate the result to the rest of my application as Set<Class<? extends GenericTypeHere<?>>> but simple cast does not work as I expect.

EDIT: Solution

Thanks for the answers, here is how I get it working in the end:

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

回答1:


Okay, so this is due to a subtle semantic difference.

List

This is the raw type of List, which equates to T being of type Object. So it's the same as saying:

List<Object>

Now, the Compiler knows for a fact, that whatever happens, this is a subclass of type Object. And if you do..

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

It will work fine! This is because Object is the same or it is some derivation of the type.

List<?>

This is literally a list of unknown (Java Docs). We don't even know that the subclass of the things in here are of type Object. In fact, the ? type is an unknown type all on its own. It has nothing to do with Object! This is why when you try and do..

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

You get a compile time error!




回答2:


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

works

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

would imply Set<Class<YourClass extends AnotherClass<YourClass>>> as mentioned in the above wildcard answer

What stops you from using

Set<Class<YourClass extends AnotherClass>> to propagate throughout your app?



来源:https://stackoverflow.com/questions/29055497/listlist-and-listlist-are-incompatible-types-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!