• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

generic question

 
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ]
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 247
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.


 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Edmen Tay
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator



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
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Below is the left out part:

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


Regards,
Edmen
 
Ranch Hand
Posts: 324
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Himalay Majumdar
Ranch Hand
Posts: 324
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 324
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 324
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

<? 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 ]
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic