Reputation: 3882
Following code produce error:
class A {
public static class C<T> {
public ArrayList<C<T>> lst;
}
public void main(String[] args) {
C<?> o = new C<>();
ArrayList<C<?>> l = o.lst;
}
}
Error message:
a.java:10: error: incompatible types: ArrayList<C<CAP#1>> cannot be converted to ArrayList<C<?>>
ArrayList<C<?>> l = o.lst;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
It says that types are different but if I substitute ? for T in then It becomes ArrayList<C<T>>
same as type of list l.
What is wrong with my reasoning?
Upvotes: 0
Views: 1909
Reputation: 131396
The compiler accepts to assign to a generic collection a collection with a subtype of the generic only if the variable target of the assignment doesn't allow to add elements in the collection.
That protects generic collections against adding that doesn't match with the type declared by the subtype of the collection.
Your problem is that by declaring l
in this way:
ArrayList<C<?>> l
you may add any C
instance in :
l.add(new C<String>());
l.add(new C<Integer>());
By assigning o.lst
to l
, you could so add anything in o.lst
whatever its declared generic.
So the compiler doesn't accept this assignment :
ArrayList<C<?>> l = o.lst;
If now you write :
ArrayList<?> l = o.lst;
It will be fine as l
doesn't allow any adding but null
.
Upvotes: 1