Consider the following program:
public class WCVsT {
private void fooWC(List<? extends Number> l ) {
l.add(l.get(0)); // 1 - A Compile time error
}
private <T extends Number> void fooT(List<T> l) {
l.add(l.get(0)); // 2 - No compile time error
}
}
I have a couple of questions regarding it:
List<? extends Animal> because I could have passed dogs to fooWC but what my program shows now should always be safe. Isn't it? Any help/hint will be greatly appreciated. Thanks in advance.
The reason one works and the other doesn't is that while both methods use the bound <T extends Number>, in the second method (the typed method), the type although unknown, is the same type throughout the method - the type is locked to a particular (but unknown) type for the duration of the call.
In the first method (the untyped one), the compiler knows only that the list of unknown is having added to it an unknown type, which is possibly a different unknown type. The fact that it's obvious to humans that it must be the same type because the target and source are the same object are invisible to the compiler.
The first version is considered by the compiler to be in the same bucket as:
List<Integer> list1;
List<Double> list2;
list1.add(list2.get(0);
It just knows that the types are both bounded by Number, but not necessarily the same type.
The second version is in the same bucket as:
List<Integer> list1;
List<Integer> list2;
list1.add(list2.get(0);
The compiler doesn't know the type, but knows it's the same type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With