user3579222
user3579222

Reputation: 1430

Adding Object to Generic List with two types

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

Answers (3)

sagar varsani
sagar varsani

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

oskansavli
oskansavli

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

talex
talex

Reputation: 20455

d should have type A<B<? extends Object>> or compatible.

Upvotes: 3

Related Questions