I was reading the book Java Generics and Collections By Maurice Naftalin, Philip Wadler, and within the first two chapters I ended up in having my head messed up with doubts. I was not able to figure out the answers.
In the call:
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");
During call to the function 'copy':
1st parameter: ?= Object
2nd Parameter: ?=Integer
But what is the datatype of T? How is it decided by jvm based on the erasure implementation?
It is said in the book that: In the line Collections.copy(obj,ints), the type parameter T is taken to be Number. The call is permitted because objs has type List<Object>, which is a subtype of List<? super Number> (since Object is a supertype of Number, as required by the super) and ints has type List<Integer>, which is a subtype of List<? extends Number> (since Integer is a subtype of Number, as required by the extends wildcard).
But as Integer implements Serializable and Comparable both, aprt from extending Number class and Object class is the super type of Serializable and Comparable also.
So why not that T is taken as Serializable or Comparable instead of Number, because the Substitution Principle will allow it to be taken.
Thanks in advance.
http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
From the 'simple' example the JLS says it chooses the most specific type that satisfies all the constraints it generates.
15.12.2.7 Inferring Type Arguments Based on Actual Arguments
A supertype constraint T :> X implies that the solution is one of supertypes of X. Given several such constraints on T, we can intersect the sets of supertypes implied by each of the constraints, since the type parameter must be a member of all of them. We can then choose the most specific type that is in the intersection
Copy.java:11: incompatible types
found : java.lang.Integer[]
required: java.lang.String[]
String[] res = copy(Arrays.<Object>asList(2, 3.14, "four"), Arrays.asList(5, 6));
^
1 error
➜ /tmp cat Copy.java
import java.util.*;
public class Copy {
public static <T> T[] copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
return null;
}
public static void main(String[] args) {
String[] res = copy(Arrays.<Object>asList(2, 3.14, "four"), Arrays.asList(5, 6));
}
}
T is decided based upon the arguments but can be specified explicitly as well. So, yes it can be Comparable and Serializable.
All of these are valid:
Collections.<Number>copy(objs, ints);
Collections.<Comparable>copy(objs, ints);
Collections.<Serializable>copy(objs, ints);
Collections.<Integer>copy(objs, ints);
Collections.copy(objs, ints); // implicitly Integer
When no type is specified Integer is picked due to the way <? extends Integer>
is handled and explained in java documentation
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