This week's book giveaway is in the Mac OS forum. We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line! See this thread for details.
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.
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?
Joined: Sep 06, 2009
hey i didnt know that we cant get thing when we use super....
Sorry to say Edwin but I'm still not clear on this!! lets take this example:
Joined: Sep 06, 2009
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
Joined: Oct 13, 2009
Because basically <? extend > is used to get things from List.
Joined: Sep 06, 2009
Joined: Dec 31, 2004
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.
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.