Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incompatible type with Arrays.asList()

Tags:

java

generics

In the following example, if I have multiple types in the list it compiles ok, but if I have one element, it chooses a different type which is no longer assignable.

// compiles fine List<Class<? extends Reference>> list = Arrays.asList(SoftReference.class, WeakReference.class); // but take an element away and it no longer compiles. List<Class<? extends Reference>> list2 = Arrays.asList(WeakReference.class); // without giving the specific type desired. List<Class<? extends Reference>> list3 = Arrays.<Class<? extends Reference>>asList(WeakReference.class); 

I am sure there is a logical explaination for this, but it escapes me.

    Error:Error:line (30)error: incompatible types required: List<Class<? extends Reference>> found:    List<Class<WeakReference>> 

Why does having two elements compile but one element does not?

BTW: It is hard to find a simple example, if you try

List<Class<? extends List>> list = Arrays.asList(ArrayList.class, LinkedList.class);      Error:Error:line (28)error: incompatible types required: List<Class<? extends List>> found:    List<Class<? extends INT#1>> where INT#1 is an intersection type: INT#1 extends AbstractList,Cloneable,Serializable 

This doesn't compile either (it won't even parse)

List<Class<? extends AbstractList & Cloneable & Serializable>> list = Arrays.asList(ArrayList.class, LinkedList.class);  Error:Error:line (30)error: > expected Error:Error:line (30)error: ';' expected 

but this compiles fine

static abstract class MyList<T> implements List<T> { } List<Class<? extends List>> list =          Arrays.asList(ArrayList.class, LinkedList.class, MyList.class); List<Class<? extends List>> list =          Arrays.<Class<? extends List>>asList(ArrayList.class, LinkedList.class); 

EDIT: Based on Marko's example. In these four example, one doesn't compile, the rest produce the same list of the same type.

List<Class<? extends Reference>> list = new ArrayList<>(); list.add(SoftReference.class); list.add(WeakReference.class); list.add(PhantomReference.class);  List<Class<? extends Reference>> list = new ArrayList<>(      Arrays.asList(SoftReference.class)); list.add(WeakReference.class); list.add(PhantomReference.class);  List<Class<? extends Reference>> list = new ArrayList<>(      Arrays.asList(SoftReference.class, WeakReference.class)); list.add(PhantomReference.class);  List<Class<? extends Reference>> list = new ArrayList<>(      Arrays.asList(SoftReference.class, WeakReference.class, PhantomReference.class)); 
like image 388
Peter Lawrey Avatar asked Dec 30 '12 15:12

Peter Lawrey


People also ask

What is asList method?

The asList() method of java. util. Arrays class is used to return a fixed-size list backed by the specified array. This method acts as a bridge between array-based and collection-based APIs, in combination with Collection.

Does arrays asList return Unmodifiable list?

Arrays. asList() method returns a fixed-size list backed by the specified array. Since an array cannot be structurally modified, it is impossible to add elements to the list or remove elements from it. The list will throw an UnsupportedOperationException if any resize operation is performed on it.


1 Answers

Interesting problem. I think that what's going on is this. When you have two elements like you show, the return type from asList is most specific type of all the arguments, which in your first example is List<Reference>. This is assignment-compatible with List<? extends Reference>. When you have a single argument, the return type is the specific type of the argument, which is not assignment-compatible because generics are not covariant.

like image 152
Ted Hopp Avatar answered Sep 19 '22 13:09

Ted Hopp