Reputation: 1430
I read a couple of posts such as here but I was unable to find the solution for my problem.
Why I am unable to add d? It is a subtype of Object...
Type of d: A<B<X>>
List<A<B<? extends Object>>> rv=new LinkedList<>();
rv.add(d); //not working
EDIT
I tried to simplify the problem. When I do:
A<B<?>> abcv=new A<B<String>>();
I get the error: Type mismatch: cannot convert from A<B<String>> to A<B<?>>
However, String is compatible with "?" - so why is it not working? I want to add elements to a list where the last type can by anything, something like this:
List<A<B<?>>> rv=new LinkedList<>();
rv.add(new A<B<X>>());
rv.add(new A<B<String>>());
rv.add(new A<B<Integer>>());
Upvotes: 6
Views: 1770
Reputation: 573
List<A<B<?>>> rv = new LinkedList<>();
? in generic means any type.
For example:
You can assign any type of generic list to List<?>
but you can not add any type of object into list because compiler does not know what type it is because of wildcard(?)
List<?> genericList1 = new ArrayList<String>();
List<?> genericList2 = new ArrayList<Integer>();
List<?> genericList3 = new ArrayList<X>();
/**
* Compiler will allow to assign any type of generic list to List<?>
* but it will not allow to add.
*/
genericList1.add("xyz"); // It will give compiler error
The <?>
wildcard allows a list of ANY type to be assigned, but the add() method is not valid on that list because you could put the wrong kind of thing into the collection. Compiler does not know which type you would pass because of wildcard(?).
If you want to add any type of object to your list than you can take list like this.
List<Object> rv = new LinkedList<>();
rv.add(new A<B<X>>());
rv.add(new A<B<String>>());
rv.add(new A<B<Integer>>());
Now compiler knows that rv is the list which accept only Object type, so compiler will not complain anything.
Upvotes: 2
Reputation: 313
List<SubClaz>
is not a subtype of List<SuperClaz>
in Java. That's why the wildcards are used: List<SubClaz>
is a subtype of List<? extends SuperClaz>
.
Now for your A<B<?>> abcv=new A<B<String>>();
example:
By adding the wildcard, you're making B<String>
a subtype of B<?>
, but since these are also wrapped by another type A
, we're back to the first problem:
A<B<String>>
is not a subtype of A<B<?>>
(Notice B<?>
is the SuperClaz
and B<String>
is the SubClaz
in this case).
You can fix this the same way; by adding another wildcard:
A<B<String>>()
is a subtype of A<? extends B<?>>
.
Keep in mind that this doesn't allow you to read or manipulate the list as you want. Search for covariance and contravariance for more detail. Here is a good one: http://bayou.io/draft/Capturing_Wildcards.html
Upvotes: 3