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));
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With