File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes generic question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "generic question" Watch "generic question" New topic
Author

generic question

Edmen Tay
Ranch Hand

Joined: Oct 21, 2008
Posts: 39
Hi all,
I had try compile this,



But when i cast the (Integer) new Object(). then it work fine.

My question is, reference type is "? super Integer", then it should be able to accept Object, as Object is a super type of Integer? Am I correct?

Please help.

Regards,
Edmen
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
My question is, reference type is "? super Integer", then it should be able to accept Object, as Object is a super type of Integer?


The wild card notations of *? super someclass/interface* and *? extends someclass/interface* are used to define the generic parameter type of a Collection.
If i define a collection of as List<? super Dog>; listDogs
then i am telling the compiler that *listDogs* can be assigned any reference of a generic collection which contains objects of type Dog or super type of Dog. So, if i have the following classes:


then i can say,
List <? super Dog> listDogs = new ArrayList<Animal>();
or
List <? super Dog> listDogs = new ArrayList<Object>();

list.add(new Dog());
list.add(new Puppy());


I am free to add any Dog or a subclass of Dog object to it because the compiler knows that no matter what, the Dog or its subclass object is going to pass the IS-A test for the type (actually a supertype of Dog) of objects stored in the actual collection ( which i am actually modifying i.e. the ArrayList of Animals or Objects in this case).

But, i cannot add a super type of Dog into *listDogs* the reason being the following scenario:


If i say,
List <? extends Dog>; listDogs = new ArrayList<Animal>(); //Compiler error then, the compiler will not allow as the extends keyword means Dog or its subclass type can be assigned to the listDogs collection.
So, List<? extends Dog> listDogs = new ArrayList<Puppy>();is a valid assignment.

listDogs.add(new Dog());// compiler error
listDogs.add(new Puppy());// compiler error

I can't add to *listDogs* as the compiler is not sure as to which type of collection may be assigned to *listDogs*.
For *? extends* wild card the compiler does'nt know to what level down the class hierarchy of class *Dog* the actual collection type can belong to. So it's even more dangerous in case of *? extends* to allow somebody to even add to the collection. Hence i am not allowed to add anything.

[ December 15, 2008: Message edited by: Harvinder Thakur ]
[ December 15, 2008: Message edited by: Harvinder Thakur ]

thanks
Harvinder
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18113
    
  39

But when i cast the (Integer) new Object(). then it work fine.


And you also "broke" the collection. Generally, if the compiler complains that you need a particular item, forcing it is not a good idea. If you want to force it, why bother using generics?


My question is, reference type is "? super Integer", then it should be able to accept Object, as Object is a super type of Integer? Am I correct?


No. You are not correct. "? super Integer" does *not* mean that it can accept any type that is a super of Integer. It means that it accepts an unknown type that is a super of Integer. So, in order to add to the list, you must add the unknown type -- and the only types that can be any unknown type of super of Integer, is Integer, as an Integer IS-A all super types of Integer.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
victor kamat
Ranch Hand

Joined: Jan 10, 2007
Posts: 247
Consider the code below.

Line 4: instead of <B> we could not have <D>; but <C>, <A> or <Object> are ok because they are each parent of C; (D is a child of C).

Lines 6, 7: adding instances of C and D is okay because each is a C and therefore guaranteed to be an A, B, or C.

Lines 8, 9: adding instances of A or B is an error, because neither is guaranteed to be a C.




( Jesper Young: Corrected code tags )
[ December 15, 2008: Message edited by: Jesper Young ]
victor kamat
Ranch Hand

Joined: Jan 10, 2007
Posts: 247
Because of bad code presentation here it is again:
Consider the code below.

Line 4: instead of <B> we could not have <D>; but <C>, <A> or <Object> are ok because they are each parent of C; (D is a child of C).

Lines 6, 7: adding instances of C and D is okay because each is a C and therefore guaranteed to be an A, B, or C.

Lines 8, 9: adding instances of A or B is an error, because neither is guaranteed to be a C.


Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 13872
    
  10

Originally posted by victor kamat:
Because of bad code presentation here it is again: ...

Note that there is an edit button that looks like this: above your post, which you can use to edit your post - no need to post the whole thing again.


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Edmen Tay
Ranch Hand

Joined: Oct 21, 2008
Posts: 39
Hi Henry,
No. You are not correct. "? super Integer" does *not* mean that it can accept any type that is a super of Integer. It means that it accepts an unknown type that is a super of Integer. So, in order to add to the list, you must add the unknown type -- and the only types that can be any unknown type of super of Integer, is Integer, as an Integer IS-A all super types of Integer.


Can i said "? super Integer" is an unknown type can be stored in the collection whereby with the condition must pass the IS-A Integer test? then what else of super class of Integer can be added?

Hi Harvinder Thakur,

I had put some remark at your explanation.

List <? super Dog> listDogs = new ArrayList<Animal>(); //wildcard with super then listDogs is allow to reference type of Animal (super class of dog)
listDogs.add(new Dog());//Dog passed Is-an Animal test

listDogs.add(new Puppy());//Puppy passed Is-an Animal test
//fine as Puppy is subclass of Dog
listDogs.add(new God());//God failed Is-an Animal test


This is logic and make me clear. But the below quote:

List <? extends Dog>; listDogs = new ArrayList<Animal>(); //Compiler error, because listDogs trying to reference ArrayList with type Animal, but Animal failed Is-A Dog test //Statement 1

So, List<? extends Dog> listDogs = new ArrayList<Puppy>();//is a valid assignment, because listDogs trying to reference ArrayList with type Puppy and Puppy passed Is-A Dog test //Statement 2

listDogs.add(new Dog());// compiler error? refer Statement 2? but it passed the Is-A Dog test
listDogs.add(new Puppy());// compiler error? refer Statement 2? but it passed the Is-A Dog test

For *? extends* wild card the compiler does'nt know to what level down the class hierarchy of class *Dog* the actual collection type can belong to. So it's even more dangerous in case of *? extends* to allow somebody to even add to the collection.


Then what can be added into the list?

Thanks and appreciate the explanations posted from you guys.

Regards,
Edmen
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18113
    
  39



Then what can be added into the list?


Keep in mind, that it is silly to purposely work with unknown types (wildcards), if you don't have to. You do so because you want to write code that can work with a broad set of generic types. In this example, you may want to write a method that can handle a list that can any type that extends Dog.

But it comes with a price. In this case, since you don't know what type the list actually hold, you can't add anything to the list. If you need to add something to the list, then you can't work with an unknowm type that extends Dog, you need to know the type.

Henry
[ December 15, 2008: Message edited by: Henry Wong ]
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Let's take an example for *? extends* wildcard notation:



The above two calls to the add() method are O.K. from the perspective of the compiler but since the compiler removes the type info using type erasure such that the JVM at runtime does not have any type info hence, the above code would crash at runtime at line no. 6 above. So even though generics are supposed to be type safe we break the type safety of generics by adding something to a list which uses *? extends someclass/interface* notation.

Hope i make sense.
Edmen Tay
Ranch Hand

Joined: Oct 21, 2008
Posts: 39
Hi all,
I try to understand the below code in IDE. and put some of my understanding comment


Please correct if i am wrong.

Thank you

Regards,
Edmen
Edmen Tay
Ranch Hand

Joined: Oct 21, 2008
Posts: 39
Hi,
Below is the left out part:

lst5.add(new Object());//will not compile as it is unknown type of subclass AA


Regards,
Edmen
Himalay Majumdar
Ranch Hand

Joined: Sep 28, 2008
Posts: 324
Originally posted by Harvinder Thakur:
[QB]

If i define a collection of as List<? super Dog>; listDogs
then i am telling the compiler that *listDogs* can be assigned any reference of a generic collection which contains objects of type Dog or super type of Dog. So, if i have the following classes:


then i can say,
List <? super Dog> listDogs = new ArrayList<Animal>();
or
List <? super Dog> listDogs = new ArrayList<Object>();

list.add(new Dog());
list.add(new Puppy());


I am free to add any Dog or a subclass of Dog object to it because the compiler knows that no matter what, the Dog or its subclass object is going to pass the IS-A test for the type (actually a supertype of Dog) of objects stored in the actual collection ( which i am actually modifying i.e. the ArrayList of Animals or Objects in this case).

But, i cannot add a super type of Dog into *listDogs* the reason being the following scenario:




So, Does it mean this is possible
listDogs.add(new Animal())

if NOT.. then what does Super type imply


SCJP 1.6, SCWCD 5.0, SCBCD 5.0 [loading..]
Himalay Majumdar
Ranch Hand

Joined: Sep 28, 2008
Posts: 324
Hi Edmen,

You quoted,



how is it possible that that unknown super type is BB in the second statement above.

Thanks
[ December 17, 2008: Message edited by: Himalay Majumdar ]
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Originally posted by Himalay Majumdar:

So, Does it mean this is possible
listDogs.add(new Animal())

if NOT.. then what does Super type imply


Super type implies the generic type of the ArrayList i.e. Animal which is being assigned to the List listDogs which can only be assigned a collection which IS-A List.

List <? super Dog> listDogs = new ArrayList<Animal>();

So, above listDogs can be assigned any List which contains a supertype of Dog or Dog itself.
Actually the restriction posed by the compiler on additions to a generic typed Collection is better appreciated if we take the scenario of a method which takes an argument of List <? super Dog> listDogs and the method calling code assigning the ArrayList<Animal> to the method argument.


As you can see the *ONLY* safe addition that i can make to a collection which accepts a type T or it supertypes T' is T or its subtypes to that collection as demonstrated above.
But had it been *? extends* wild card notation( implying only Dog or its subtypes can be assigned) then adding subtype of Dog or even Dog itself to the listDogs collection would have been risky because the subtype passes the IS-A test for the supertype and not the supertype for its subtypes.

Hope it makes sense
[ December 17, 2008: Message edited by: Harvinder Thakur ]
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Originally posted by Edmen Tay:

List<? super AA> lst1 = new ArrayList<AA>();//lst1 can contain AA,BB,CC,DD and unknown type that is super type of AA
List<? super BB> lst2 = new ArrayList<BB>();//lst2 can contain BB,CC,DD and unknown type that is super type of BB
List<? super CC> lst3 = new ArrayList<BB>();//lst3 can contain CC,DD and unknown type that is super type of CC
List<? super DD> lst4 = new ArrayList<CC>();//lst4 can contain DD and unknown type that is super type of DD


<? super AA> implies that lst1 can be *assigned* AA or its SuperType. BUT, you can only add AA or it's SubTypes to lst1 because that is the only addition which guarantees typesafety and therefore the compiler gives thumbs up.

<? extends AA> implies that the list can be *assigned* AA or its SubTypes. BUT, you can add nothing to it since if you were allowed to add an object to it then the typesafety boasted to be given by Generics will be GONE! So, consider it that adding generics to the java programming language had to bring about such vagaries and complications just to make your code typesafe.
Himalay Majumdar
Ranch Hand

Joined: Sep 28, 2008
Posts: 324
I dont want to sound silly. Looking at your post i feel <? extends AA> should do wat <? super AA> is doing. And there should be nohing like <?super AA> existing.
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Originally posted by Himalay Majumdar:

I dont want to sound silly. Looking at your post i feel <? extends AA> should do wat <? super AA> is doing. And there should be nohing like <?super AA> existing


Well, huh.... :roll: IMHO <? extends> and <? super > are opposites of each other. If your current state of understanding has got to do with how i have explained the concept then i would request you to quote the portion of my post causing the misunderstanding.
Also, I think the best thing would be for you guys to go through the generics tutorial once. Here is the Generics Link
Himalay Majumdar
Ranch Hand

Joined: Sep 28, 2008
Posts: 324
<? super AA> implies that lst1 can be *assigned* AA or its SuperType. BUT, you can only add AA or it's SubTypes to lst1 because that is the only addition which guarantees typesafety and therefore the compiler gives thumbs up.

<? extends AA> implies that the list can be *assigned* AA or its SubTypes. BUT, you can add nothing to it since if you were allowed to add an object to it then the typesafety boasted to be given by Generics will be GONE! So, consider it that adding generics to the java programming language had to bring about such vagaries and complications just to make your code typesafe.


The above highlighted statements made me say. <? super AA> is doing what <? extends AA> should do

But You are right, I actually jumped into the topic without knowing much about generics. Thanks for the link
[ December 17, 2008: Message edited by: Himalay Majumdar ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: generic question
 
Similar Threads
Adding elements into generic list doubt
one more doubt abt generics
Why not compile?
Generics
A Generic Question