Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

generics extends question?

 
Minhaj Mehmood
Ranch Hand
Posts: 400
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
on page# 618 K&B
By saying <? extends Animal>, we're saying, I can be assigned a collection that is a subtype of List and typed for <Animal> or anything that extends Animal.


can anyone explain me the above and difference between <? extends Animal> and <? super Animal>


-Minhaj
 
rohan yadav
Ranch Hand
Posts: 156
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
<? extends Animal> means any subclass of Animal can use <?extends Animal>.
<? super Animal> means any superclass of Animal can use<? super Animal>.
 
Minhaj Mehmood
Ranch Hand
Posts: 400
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks rohan
 
rohan yadav
Ranch Hand
Posts: 156
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
e.g consider following code


For above method addAnimal we can pass any argument that passes IS-A test for Animal class, i.e subtype of Animal class




Above code tells that we can pass any superclass of Dog class to method addAnimal.
 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
dude i think in the first code...add will give a compile error
 
W. Joe Smith
Ranch Hand
Posts: 710
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankur kothari wrote:dude i think in the first code...add will give a compile error


Why do you think it will give a compiler error?
 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
when ? extends Animal is used nothing can be added to the list.
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

can anyone explain me the above and difference between <? extends Animal> and <? super Animal>


The best way to explain it is with an example. Basically you use extends when you intend to get things from the collection, but you do not intend to add items, and you use super when you intend to put things in the collection, but you do not intend to extract them.

Why so?

Consider the following scenario:



But you can do this, knowing for sure that all items in the list are numbers, right?:



Now consider this another one:



Do you get it now?
 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hey i didnt know that we cant get thing when we use super....
 
Ankit Garg
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankur kothari wrote:hey i didnt know that we cant get thing when we use super....

You can get elements from a List<? extends Number> but only into references of type Object i.e. Object obj = list.get(0);
 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ankit did you mean List<? super Number> ???
 
Ankit Garg
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankur kothari wrote:ankit did you mean List<? super Number> ???

I was just trying to show the syntax. The correct syntax would of course have an identifier for the name of the List...
 
Minhaj Mehmood
Ranch Hand
Posts: 400
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edwin Dalorzo wrote:Do you get it now?


Sorry to say Edwin but I'm still not clear on this!! lets take this example:

 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
dude there is a difference between the two....? extends Animal mean anything can be accepted which extends Animal.....like Dog....so the compiler doesnt know which one at compile time...you can also add suppose a cat....whcih the compile is trying to avoid...so an error....becasue generics is all about compile time

understood?
 
rohan yadav
Ranch Hand
Posts: 156
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because basically <? extend > is used to get things from List.

 
Ankur kothari
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
exaclty
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, let's try again to clear this. Generics creates certain confusion when it comes to the rules of inheritance.



As you can see in the code above, since the List is a List of Number, it can contain any kind of object that is a Number. Right?
Basically, Integer, Float, Double and BigInteger, all of them inherit from Number, and therefore they all are a Number. Correct?

However, you are not allowed to do this:



You might think this weird, because ArrayList implements List and Integer is a Number.
Still, this is not valid. Why?

Well, for a moment imagine that the code above really compiled. See what you could do...



See the problem? The compiler must guarantee that the collection contains objects only of the declared type.

So fortunately, this is not possible thanks to the compiler.
Unfortunately, it makes very difficult to write generic code.

For instance, you are creating a method to print all items in a Lists containing Numbers.

Let's say you declare it like this:




Based on the previous understanding, you could never invoke this method unless you were passing a List of Numbers and just that.
But what if you want to print an List<Integer> or a List<Float> or a List<BigDecimal>, you would need a method for every case.
That would be illogical, right?

Then you can do this:



Now you can pass any List whose parameterized type extends Number. Right?

You could do things like this:



But, there is no free lunch. You have to pay price.

For instance, take a look at this code:



Why, the last line produces a compile time error?

Simple, because you cannot guarantee that a List<? extends Number> is a List of Integers.
In fact, in this case it is a List of Doubles.

So, when you use extends in a generic type, it means you can read items, but you cannot write them.

How about this time, did you get it?
 
Jack Bento
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
great explanation. thanks
 
Neha Daga
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
that was great, it really helped.

thanks
 
Minhaj Mehmood
Ranch Hand
Posts: 400
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edwin Dalorzo wrote:
How about this time, did you get it?


Great such a nice explanation, now i understand extends is all about read!!

Thanks alot!


Minhaj
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Excellent! Now the opposite case, with ? super T



Evidently, we can add all kinds of objects to this list.

But now, we use generics:



Now, this proves that we can write into the list, but if you try this:



Why? Well, the compiler cannot ensure that the original list does not contain other types of objects different from CharSequence.
Actually, in this case, the original list contains an Integer in this position. So, at runtime this would have failed. Right?

That's why you can write things into this type of lists, but you cannot read from them (at least not without casting).

Lets say I want to right a method to copy items from one list to another. You could do somewhat like this:



Unfortunately, as we saw before, this would require that we strictly pass a List of Objects in every case, and what if we want to copy Strings, or StringBuilders or CharBuffers?

Then, according to what we learnt, you could suggest changing the method to this:



But now, you get a compile time error, basically, because you cannot write items into this list, because the compiler cannot ensure its contents.

However, we could fix it like this:



Now, you can read from List<? extends Object> src and write items to List<? super Object> dest.
 
Neha Daga
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thats great....I was about to ask that question.
 
Minhaj Mehmood
Ranch Hand
Posts: 400
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Excellent
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic