gpt4 book ai didi

Java通配符具有 super 意外的行为

转载 作者:行者123 更新时间:2023-11-30 03:50:21 25 4
gpt4 key购买 nike

我编写了一个 Fruit 类,它实现了 Comparable 接口(interface)和 2 个子类:Apple 和 Orange。我编写了一个方法,它返回 2 个水果之间的最大值(无论它意味着什么)。

请注意,我没有在 super 中使用任何通配符。

我认为 max 方法会失败,因为 Comparable 接口(interface)不是由 Apple 或 Orange 直接实现的。

问题:为什么建议使用这种形式的通配符:

<T extends Comparable<? super T>>

如果没有 super 也能工作吗?

这是代码:

package main;

//Note that I did not use the super wildcard: <T extends Comparable<? super T>>
class Max {

public static <T extends Comparable<T>> T getMax(T x, T y) {
return x.compareTo(y) >= 0 ? x : y;
}
}

class Fruit implements Comparable<Fruit> {
public String name;

public Fruit(String name) {
this.name = name;
}

@Override
public int compareTo(Fruit other) {
return name.compareTo(other.name) == 0 ? 0 :
name.compareTo(other.name) > 0 ? 1 : -1;
}

}

class Apple extends Fruit {
String name;

public Apple(String name) {
super(name);
}

}

class Orange extends Fruit {
String name;

public Orange(String name) {
super(name);
}

}

public class Main {

public static void main(String[] args) {

Apple a = new Apple("apple");
Orange o = new Orange("orange");
Fruit f = Max.getMax(a, o); //It should not be allowed because T does not implement Comparable directly
System.out.println(f.name);

}
}

最佳答案

就您而言,T可以选择为Fruit ,以及声明 Fruit f = Max.getMax(a, o);会正确进行类型检查。因此,它有效。

Max.getMax()具有参数类型 T ,以及 T 子类型的实例也是 T 的实例,因此该方法接受 T 的任何子类型作为参数。

但是请注意,您的方法仍然存在 T 的问题只能推断为Fruit ,而不是Apple ,因此您无法返回 Apple :

Apple a = Max.getMax(apple1, apple2);

但是,请考虑 T是泛型类型参数:

public static <T extends Comparable<T>> T getMax(List<T> xs) {
//...
}

泛型不是协变的,所以这个方法只能接受List<Fruit> ,但不是List<Apple>List<Orange> ,尽管 Apple s 可以与 Apple 进行比较等

如果将其更改为:

public static <T extends Comparable<? super T>> T getMax(List<T> xs) {
//...
}

那么它就可以工作 List<Apple>List<Orange> .

关于Java通配符具有 super 意外的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24629547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com