Collections.max方法类型参数声明签名<t extends =“”可比较<?=“”super =“”t =“”>&gt;解释

时间:2017-08-04 07:32:10

标签: java generics wildcard

在第3章比较和界限 Java Generics by Naftalin和wadler 中,它将 Collections.max 方法的示例视为< / p>

<T extends Comparable<? super T>> T max(Collection<? extends T> coll)

<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

第二个签名是Java api(为了向后兼容)。

根据Get -put原则,我了解制作人扩展消费者超级

现在举一个例子如下:

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
    }
}

现在说:

此示例说明了为什么需要此通配符。如果我们想比较两个 我们在前面的代码中将T视为橙色:

Orange extends Comparable<? super Orange>

这是正确的,因为以下两个都有:

Orange extends Comparable<Fruit> and Fruit super Orange

如果没有超级通配符,找到List<Orange>的最大值将是非法的, 即使允许找到List<Fruit>的最大值

我明白了这个例子中的所有内容除了行没有超级通配符,找到List<Orange>的最大值是非法的

我发现自己处于不明朗的境地。但是我在stackoverflow上解释了Collections.max方法签名的许多答案(我确实理解签名,可能不完全)。

1 个答案:

答案 0 :(得分:3)

你错误地引用了这本书。该声明是关于Fruit implements Comparable<Fruit>的情况。在这种情况下,Orange不会成为<T extends Comparable<T>>的有效候选者,因为Orange未实现Comparable<Orange>。因此,除List<Orange>之外,您无法将List<T>作为<T extends Comparable<? super T>>传递,这可确保通过Orange超类可以将一个Fruit与另一个compile 'com.google.firebase:firebase-messaging:10.0.1' compile 'com.google.android.gms:play-services-maps:11.0.4' compile 'com.google.android.gms:play-services-location:11.0.4' 进行比较