aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes wildcard, super, add objects to collection Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "wildcard, super, add objects to collection" Watch "wildcard, super, add objects to collection" New topic
Author

wildcard, super, add objects to collection

Michal Burak
Greenhorn

Joined: Oct 05, 2009
Posts: 7


Why does this not compile?
As I understand x should store any element that is a super type of String (? super String)?

Thanks for help.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19064
    
  40

As I understand x should store any element that is a super type of String (? super String)?


No. "? super String" doesn't mean a list that can store any element that is a super type of String. It means that it is a list can can store a particular type, that type is something that is bounded (a super type of string). And the compiler doesn't know what it is.

In other words, the list could be a list of objects, or a list of strings, and the compiler must type check it to work with both types of lists -- the code will work regardless if you pass it a list of objects or a list of strings.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Guillaume Jeudy
Greenhorn

Joined: Jul 27, 2009
Posts: 24
I agree with Henry but I think that Sun screwed up the syntax on this one. It is absolutely counter-intuitive and I would guess that the lack of reification in java generics is the root cause of such an awkward language design feature.

I could only remember by pounding into my head a few rules for bounded generics + collections below:

? super *type*: You cannot get() from the collection, you can add() or put() as long as the parametrized type is *type* or a subclass of *type*.

? extends *type*: You can get() from the collection as long as the parametrized type is *type* or a super class of *type*. You cannot add or put to the collection.

?: This is an unknown type, therefore the collection is read-only and the get() operation cannot be implicitly casted to anything other than Object!



SCJP 1.4 and 6.0, SCJD
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

? super *type*: You cannot get() from the collection,


Actually you can get elements out of such collection, you can assign such an element to a reference of type Object



The syntax MAY look counter intuitive in the beginning, but after you learn generics to a certain extent, this becomes intuitive. I never felt that this was counter intuitive (but that's just me)...


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
aslika bahini
Ranch Hand

Joined: Mar 03, 2007
Posts: 111
Hi There,



Can anyone please explain the above code. please correct me."List<? super TestSuper> xvar" can contain anything super of TestSuper or itself. Why am I getting the error
"super TestSuper> is not applicable for the arguments (Base)".

Thanks
Saritha
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19064
    
  40

saritha babu wrote:
Can anyone please explain the above code. please correct me."List<? super TestSuper> xvar" can contain anything super of TestSuper or itself. Why am I getting the error
"super TestSuper> is not applicable for the arguments (Base)".


A slight wording modification of my previous post...

No. "? super TestSuper" doesn't mean a list that can "contain anything" that is a super type of TestSuper or itself. It means that it is a list can can store a particular type, that type is something that is bounded (a super type of TestSuper). And the compiler doesn't know what it is.

In other words, the list could be a list of objects, a list of Base, or a list of TestSuper, and the compiler must type check it to work with all possible types of lists -- the code will work regardless if you pass it a list of objects, a list of Base, or a list of TestSuper.


Henry
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

Read this FAQ if it helps...
Guillaume Jeudy
Greenhorn

Joined: Jul 27, 2009
Posts: 24
I just read the FAQ entry, even though it does make sense in explaining how ? super *type* works there is still no clear easy to understand way to differentiate the ? extends *type* from ? super *type*.

Why can you add() only with ? super *type* and get() only with ? extends *type* ?

I have yet to find a clear explanation explaining the semantic difference between the 2 notations.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19064
    
  40

Guillaume Jeudy wrote:
I have yet to find a clear explanation explaining the semantic difference between the 2 notations.


Example:

A List<? super Number> means a list of an unknown type that is a super of Number (or Number). This means that it can be a list of Number instances, or it can be a list of Object instances. It does *not* mean a list that can hold either Number or Object instance -- the list is of a particular type, it is just that the compiler doesn't know what it is.

A List<? extends Number> means a list of an unknown type that is a subclass of Number (or Number). This means that it can be a list of Number instances, it can be a list of Integer instances, it can be a list of Double instances, etc. etc. etc. It does *not* mean a list that can hold either Number, Integer, or Double instances -- the list is of a particular type, it is just that the compiler doesn't know what it is.

Guillaume Jeudy wrote:Why can you add() only with ? super *type* and get() only with ? extends *type* ?


Think about it a bit... In the first case, it can be a list a Object instances or it can be a list of Number instances. In order to do any operation, it must work for both -- meaning that you can only add something that is both IS-A Object and IS-A Number. This means that you are allowed to add Number instances, Integer instances, Double instances, etc. -- as anything that subclass Number IS-A Number, and IS-A Object.

In the second case, it can be a list a Object instances, it can be a list of Integer instances, or it can be a list of Double instances. In order to do any operation, it must work for all the cases -- meaning that you can only add something that IS-A Object, IS-A Integer, IS-A Double, etc. etc. This means that you are allowed to only add null, as that is the only thing that IS-A all possible subclasses of Number.

As for get(), that statement is completly not true. But I would let you work out why the types returns is what it is. It makes sense, you just have to think it through a bit.

Henry
Guillaume Jeudy
Greenhorn

Joined: Jul 27, 2009
Posts: 24
Thanks Henry,

I think your the first person who wrote a clear explanation on this. None of the comments on examlab, enthuware or even SCJP exam books are as clear as this. It all perfectly makes sense, it is logical if you think it through like you said.

when you get() with ? super Number, the compiler doesn't know the exact type except that it IS A Number and/or IS A Object which means you can only get an Object since it is the only class that every subclass of Number and/or Object can be.

when you get() with ? extends Number, the compiler doesn't know the exact type except that it IS A Number therefore you can assign to a Number or an Object.

Do I have this one right?

Thanks,
Guillaume
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: wildcard, super, add objects to collection