6

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>>());
3
  • You need to create an object of type A<B<? extends Object>>. This should be enough. What do you mean by "not working"? Commented Jan 2, 2019 at 9:59
  • 2
    You can't guarantee that ? extends Object can contain something of type X. It could be something else entirely like A<B<String>>. Commented Jan 2, 2019 at 10:01
  • 2
    And note that <? extends Object> is the same as <?>. Commented Jan 2, 2019 at 10:02

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

Comments

3

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

2 Comments

It never will have that exact type though, because the ? will refer to different types in the declaration of d and the one in the List's elements.
@daniu yes. It is why I said "or compatible". Should have think that there is no d with exact same type.
2
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.