【问题标题】:Collections.max method type parameters declaration signature <T extends Comparable<? super T>> explanationCollections.max 方法类型参数声明签名 <T extends Comparable<?超T>>解释
【发布时间】:2017-08-04 07:32:10
【问题描述】:

在Naftalin and wadler的Java Generics第三章比较与界限中,以Collections.max方法为例

<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 原则,我确实了解 Producer extendsconsumer super

现在举个例子如下:

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:

Orange extends Comparable<? super Orange>

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

Orange extends Comparable<Fruit> and Fruit super Orange

没有超级通配符,找到List&lt;Orange&gt; 的最大值是非法的, 即使找到List&lt;Fruit&gt; 的最大值是允许的

除了 没有超级通配符,找到List&lt;Orange&gt; 的最大值将是非法的

,我确实了解此示例中的所有内容

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

【问题讨论】:

  • 你不明白什么?
  • 为什么从 List 中找到 max 是不合法的,这意味着如果将 t 的类型定义指定为 >,它将面临什么问题

标签: java generics wildcard


【解决方案1】:

你错误地引用了这本书。该声明是关于Fruit implements Comparable&lt;Fruit&gt;的情况。在这种情况下,Orange 将不是&lt;T extends Comparable&lt;T&gt;&gt; 的有效候选者,因为Orange 没有实现Comparable&lt;Orange&gt;。因此,您不能将List&lt;Orange&gt; 作为List&lt;T&gt; 传递,除非&lt;T extends Comparable&lt;? super T&gt;&gt;,这样可以确保一个Orange 可以通过Fruit 超类与另一个进行比较。

【讨论】:

  • 我认为这是我的困惑。我无法识别语句“没有超级通配符,找到 List 的最大值将是非法的,即使找到 List 的最大值是允许的”是关于 Fruit 实施的第一个示例可比
猜你喜欢
  • 1970-01-01
  • 2012-01-22
  • 2020-08-22
  • 1970-01-01
  • 2018-12-16
  • 2022-12-17
  • 2013-08-29
  • 1970-01-01
  • 2019-10-11
相关资源
最近更新 更多