Two Laptop Bag*
The moose likes Beginning Java and the fly likes Troubles with WildCards Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Troubles with WildCards" Watch "Troubles with WildCards" New topic
Author

Troubles with WildCards

Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Hi all,

I was just wordering about the following code:



I though I understand why it produces compiler error as the following:

MyClass.java:4: cannot find symbol
symbol : method add(java.lang.String)
location: interface java.util.List<capture#622 of ? extends java.lang.String>
list.add(new String());
^
1 error

But then the following compiled just OK:



Why is that?

Thanks for all replies


SCJP/OCPJP 6
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

This is the standard thing which everybody gets wrong about wild-card type parameters.

A "List<? extends X>" is not a List which can contain anything which extends X. It is a List<Y> for some specific class Y which extends X. But we don't know at the present time what Y will be, all we know is that it will extend X.

And that means that we can't add an X object to that List, because we don't know whether X will be a subclass of Y when the List is actually created. In fact even if Z is a subclass of X, we can't add a Z object to the List because we don't know whether Z will be a subclass of Y either.

Whereas in your second example, a "List<? super X>" is a List<Y> for some class Y which is a superclass of X. In this case we can add an X element to the List, because we do know that X will be a subclass of Y.

(You chose String to be your X in this case -- that just adds to the confusion because String is a final class. But that doesn't change the interpretation of the rules which I just described.)
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

And welcome to the Ranch, Radovan!
Slaxmi Raj
Ranch Hand

Joined: Apr 20, 2012
Posts: 40
means a List of Objects that are instances of class A or sub classes of class A.
In the 1st example you are trying to subclass the String, is not possible because String is final class.
so you may try the below code.


In the 2 nd example means
any class which is super class of String
, in this case it would be Object.
so your code was compiled successfully.
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Thank you Paul:)

Paul Clapham wrote:
Whereas in your second example, a "List<? super X>" is a List<Y> for some class Y which is a superclass of X. In this case we can add an X element to the List, because we do know that X will be a subclass of Y.


Maybe I am missunderstanding you, but the following should compile based on your reply, but it doesn't:



I think that the whole problem is about the declaration of add method inside List interface:



In this way it expects concrete class, no subclasses nor superclasses. BTW also compilation errors say something like this... A problem is only mentioned piece of code:



Maybe JVM is very predictable (String vs. ? super String) in such case and lets it compile. But it is not so predictable with "extends" (String vs. ? extends String)...
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Hi Slaxmi,

your code works, but is very confusing and is not proving the actual purpose we are talking here about.

You are using the following method:



So as you can see, you are actually passing null inside the list (and so it compiles), Integer is not relevant here, because it is only index...
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

Radovan Masaryk wrote:Maybe I am missunderstanding you, but the following should compile based on your reply, but it doesn't:



Well, again you have confused the issue by using String as your basis. But let's suppose (as the compiler does) that there is a class X where String extends X and X extends Object. Then a "List<? super String>" could be a List<X>, and you can't add an Object to that because Object isn't a subclass of X.
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Paul,

Well, again you have confused the issue by using String as your basis. But let's suppose (as the compiler does) that there is a class X where String extends X and X extends Object. Then a "List<? super String>" could be a List<X>, and you can't add an Object to that because Object isn't a subclass of X.


Well why to talk if we can code

I don't think that is right, look at the following code that does NOT compile:



With the familiar error:

MyClass.java:4: cannot find symbol
symbol : method add(SubObject)
location: interface java.util.List<capture#594 of ? super SubSubObject>
list.add(new SubObject());
^
1 error
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

That's a better example. So based on what I said in my last two posts, how should you interpret "List<? super SubSubObject>"?
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

That's a better example. So based on what I said in my last two posts, how should you interpret "List<? super SubSubObject>"?


That these are legal and compiles:



They also correspond what you are talking about. What I am trying to clarify here is that the whole problem should correspond with the declaration of add method inside the List interface. Evidently WildCards are more wilder than most of us expected...
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

No. Let me say it one more time, then.

A List<? super SubSubObject> is a List<X> for some class X which is a superclass of SubSubObject.

So what kind of objects can we add to that List? We can only add objects which can be assigned to the type X. So now you should be able to explain why we can't add an object of type SubObject...
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

A List<? super SubSubObject> is a List<X> for some class X which is a superclass of SubSubObject.


But SubObject is superclass of SubSubObject.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

Radovan Masaryk wrote:
A List<? super SubSubObject> is a List<X> for some class X which is a superclass of SubSubObject.


But SubObject is superclass of SubSubObject.


Yes, it is. But that isn't the question the compiler is asking. The compiler is asking "Is SubObject a subclass of X?" And the answer is "Maybe". Now explain why the answer isn't "Yes"...
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Let me get back to original question:

This will not compile (extends):



Nor this (extends):



Nor this (super):



BUT this one compiles fine (super):



The question is why?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

I have just spent the last four posts trying to explain to you how it actually works. But I see you are not interested in that. No problem... I won't bother you any more.
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

I am really sorry Paul. I really don't want to waste your time...

Yes, it is. But that isn't the question the compiler is asking. The compiler is asking "Is SubObject a subclass of X?" And the answer is "Maybe". Now explain why the answer isn't "Yes"...


So please answer to your 4th post... And we can close the whole problem.

Thanks
Radovan Masaryk
Greenhorn

Joined: Sep 04, 2012
Posts: 14

Finally I got it...

into

can be added only SubSubObject because of the following:

(I missed this point) - what if the real object is:



Which is what Paul claimed... Really sorry Paul and thank you again.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

Excellent! Yes, that's the right answer.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Troubles with WildCards
 
Similar Threads
A Generic Question
Generics-compiler error
Generics <?>
Generics - need help
Generics Problem