Reputation: 3350
In the Java Generics by Naftalin and wadler in chapter 3 comparison and Bounds , it takes the example of Collections.max method as
<T extends Comparable<? super T>> T max(Collection<? extends T> coll)
and
<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
second signature is in Java api (for backward compatibility).
As per the Get -put principle I do understand the Producer extends and consumer super .
Now this take an example as follows:
abstract class Fruit {
protected String name;
protected int size;
protected Fruit(String name, int size) {
this.name = name; this.size = size;
}
public boolean equals(Object o) {
if (o instanceof Fruit) {
Fruit that = (Fruit)o;
return this.name.equals(that.name) && this.size == that.size;
} else return false;
}
public int hashCode() {
return name.hashCode()*29 + size;
}
protected int compareTo(Fruit that) {
return this.size < that.size ? -1 :
this.size == that.size ? 0 : 1 ;
}
}
class Apple extends Fruit implements Comparable<Apple> {
public Apple(int size) {
super("Apple", size);
}
public int compareTo(Apple a) {
return super.compareTo(a);
}
}
class Orange extends Fruit implements Comparable<Orange> {
public Orange(int size) {
super("Orange", size);
}
public int compareTo(Orange o) {
return super.compareTo(o);
}
}
class Test {
public static void main(String[] args) {
Apple a1 = new Apple(1);
Apple a2 = new Apple(2);
Orange o3 = new Orange(3);
Orange o4 = new Orange(4);
List<Apple> apples = Arrays.asList(a1,a2);
assert Collections.max(apples).equals(a2);
List<Orange> oranges = Arrays.asList(o3,o4);
assert Collections.max(oranges).equals(o4);
List<Fruit> mixed = Arrays.<Fruit>asList(a1,o3);
assert Collections.max(mixed).equals(o3); // compile-time error
}
}
Now it says :
This example shows why this wildcard is needed. If we want to compare two oranges, we take T in the preceding code to be Orange:
Orange extends Comparable<? super Orange>
And this is true because both of the following hold:
Orange extends Comparable<Fruit> and Fruit super Orange
Without the super wildcard, finding the maximum of a List<Orange>
would be illegal,
even though finding the maximum of a List<Fruit>
is permitted
I do understand everything in this example except the line Without the super wildcard, finding the maximum of a List<Orange>
would be illegal
I am finding myself in unclear situation . However I have gone many answers at stackoverflow explaining the Collections.max method signature(and I do understand that signature, might be not completely).
Upvotes: 1
Views: 165
Reputation: 50726
You're misquoting the book. The statement was made about the case where Fruit implements Comparable<Fruit>
. In such a case, Orange
would not be a valid candidate for <T extends Comparable<T>>
because Orange
doesn't implement Comparable<Orange>
. Therefore, you can't pass a List<Orange>
as List<T>
unless <T extends Comparable<? super T>>
, which ensures that one Orange
can be compared to another by means of the Fruit
superclass.
Upvotes: 3