Adam Chalkley wrote:
if you just get a compilation error when you try to add something?
That's a pleasureAdam Chalkley wrote:thanks Campbell . . .
I thought <? super Player> meant any object that is a super class of Player,but FootballPlayer is a sub class of player,that confuses me
Adam Chalkley wrote:
Player has a method called getName() how come I can't access getName()? it only gives me the options to use the methods toString,getClass etc
please note Sim,Jim,and Tim are all instances from Player with Jim been a BasketballPlayer and Tim being a FootballPlayer
All things are lawful, but not all things are profitable.
extends
The wildcard declaration of List<? extends Number> foo3 means that any of these are legal assignments:
Reading - Given the above possible assignments, what type of object are you guarenteed to read from List foo3:
You can read a Number because any of the lists that could be assigned to foo3 contain a Number or a subclass of Number. // understood
You can't read an Integer because foo3 could be pointing at a List<Double>. // understood
You can't read a Double because foo3 could be pointing at a List<Integer>. // understood
Writing - Given the above possible assignments, what type of object could you add to List foo3 that would be legal for all the above possible ArrayList assignments:
You can't add an Integer because foo3 could be pointing at a List<Double>. // understood
You can't add a Double because foo3 could be pointing at a List<Integer>. // understood
You can't add a Number because foo3 could be pointing at a List<Integer>. // 1 don't understand
You can't add any object to List<? extends T> because you can't guarantee what kind of List it is really pointing to, so you can't guarantee that the object is allowed in that List. The only "guarantee" is that you can only read from it and you'll get a T or subclass of T.
super
Now consider List <? super T>.
The wildcard declaration of List<? super Integer> foo3 means that any of these are legal assignments:
Reading - Given the above possible assignments, what type of object are you guaranteed to receive when you read from List foo3:
You aren't guaranteed an Integer because foo3 could be pointing at a List<Number> or List<Object>. // understood
You aren't guaranteed an Number because foo3 could be pointing at a List<Object>. // understood
The only guarantee is that you will get an instance of an Object or subclass of Object (but you don't know what subclass). // 2 don't really understand
Writing - Given the above possible assignments, what type of object could you add to List foo3 that would be legal for all the above possible ArrayList assignments:
You can add an Integer because an Integer is allowed in any of above lists. // 3 don't understand
You can add an instance of a subclass of Integer because an instance of a subclass of Integer is allowed in any of the above lists. // 4 don't understand
You can't add a Double because foo3 could be pointing at a ArrayList<Integer>. // understand
You can't add a Number because foo3 could be pointing at a ArrayList<Integer>. // 5 don't understand
You can't add a Object because foo3 could be pointing at a ArrayList<Integer>. 6 // don't understand
PECS
Remember PECS: "Producer Extends, Consumer Super".
"Producer Extends" - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T, e.g. List<? extends Integer>. But you cannot add to this list.
"Consumer Super" - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T, e.g. List<? super Integer>. But there are no guarantees what type of object you may read from this list.
If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List<Integer>.
Example
Note this example from the Java Generics FAQ. Note how the source list src (the producing list) uses extends, and the destination list dest (the consuming list) uses super:
public class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
}
1) why can't we add a number if Integer is a subclass of Number
All things are lawful, but not all things are profitable.
All things are lawful, but not all things are profitable.
Adam Chalkley wrote:1) why can't we add a number if Integer is a subclass of Number
2) don't really understand hard to explain
3) why are we allowed add an Integer what if the list<? super T> is pointing to List<Number> or List<Object>?
4) same question as number three but also why are we even allowed a sub class when we stay super T meaning T or any super class of T how can we add sub classes when we didn't say extends
5) why can't we add a number if Number is a super class of Integer
6) why can't we add an object if Object is a super class of Integer also
Adam Chalkley wrote:
If anyone wants to say why I got that error with the code above would greatly be appreciated
Campbell Ritchie wrote:General rough rule of thumb, which I am sure Henry has already told you.
If you have List<? extends Foo> you can get things out of it and be confident you can use them as a Foo. That means, “Whatever is in this List will be a Foo. It might be a subtype of Foo, but I don't know that. It won't matter, anyway.”
If you have a List<? super Foo> you can take things which you are confident are a supertype of Foo and put them in it. That means, “If you add a Foo to this List, I can be sure it will fit in. You can also insert a supertype of Foo, but I don't know which type. It won't matter, anyway.”
? extends→remove. Don't add
? super→insert. Don't remove.
I don't think your example with T extends E will compile. I agree: there probably is no point in trying to turn a List<Foo> into a List<? extends Foo>. Whoever told you about boxes for puppies (maybe Stephan?) showed you why you can't add anything to the List<? extends T>.
Campbell Ritchie wrote:Please review Henry's post where he explains how you can get Animals out of a List<Lion> or List<Tiger> only if you declare its type as List<? extends Animal>
Remember:
? extends Foo ⇒ take things out.
? super Foo ⇒ put things in.
Jesse Matty wrote:What is the point of writing List<? extends Foo> I have always written List<Foo> and been able to add anything that extends foo to it.Now my foo class has always been abstract though
Jesse Matty wrote:sorry it was late last night I meant to write what is the point of declaring a List as <? super Foo>
Stephan van Hulst wrote:
Jesse Matty wrote:sorry it was late last night I meant to write what is the point of declaring a List as <? super Foo>
I explained that in my last response to Adam.
Jesse Matty wrote: what is benefit to writing List<? super Double> number = new ArrayList<Number>(); as opposed to writing List<Number> number =new ArrayList<Number>():
The compiler does not run at runtime. It therefore doesn't know full stop.Adam Chalkley wrote:. . . the compiler only knows at run time . . .
Jesse Matty wrote:why have a list that can hold any kind objects that a object extends? isn't it bad practice to declare a list that can hold a type object
Jesse Matty wrote:...my question is what exactly List <? super ObjectKind> useful for?
Campbell Ritchie wrote:Remember:
? extends Foo ⇒ take things out.
? super Foo ⇒ put things in.
Jesse Matty wrote:But to add knight to a list of living things that may include plants bacteria or fungus makes no sense.
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime. |