Reputation: 866
After looking into Java's Collection class (OpenJDK 8_update40), I found the following method:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) > 0)
candidate = next;
}
return candidate;
}
I don't fully understand the use of generic types here. As far as I understand has T to be a subtype of Object which also has to implement the Comparable interface which is also parameterized via a generic parameter. The parameter of Comparable states that is have to be some supertype of T. Due to that we have some kind of recursive type definition.
But here is my question: As far as I know every type in Java is a subtype of Object, so why do they specify it within the definition of T?
Upvotes: 4
Views: 101
Reputation: 930
This is due to covariance vs. contravariance.
As a general rule:
<? extends T>
as in Iterator<? super T>
as in ComparableUpvotes: 0
Reputation: 121712
This is for backwards compatibility reasons.
When you use a generic type and this generic type has lower bounds, such as:
<T extends Foo & Bar> void someMethod(T xxx)
then the runtime signature of someMethod
will be:
void someMethod(Foo xxx)
(well, OK, the argument name is not there, but you get the picture).
Now, Collections.max()
was defined before JDK 5; and its signature was:
public static Object max(Collection coll)
which, in Java 5, could be translated as:
public static Object max(Collection<Object> coll)
The thing is that the return value of max
cannot be a Comparable
...
Of course, in this case, more difficulties are added:
Comparable
is a "consumer" in the PECS way (hence Comparable<? super T>
);Collection
passed as an argument can have any type which is either T
or anything extending T
, hence ? extends T
; we don't care about the actual type, only that the Collection
is guaranteed to return something which is at least a T.This explains the somewhat convoluted signature...
Upvotes: 6
Reputation: 714
Because if you dont use the "T" the collection would only accept instances of Object.
For example String is subtype of Object, but would not compile because the collection would only accept Object instances.
Upvotes: 0