问题<T延伸可比较>
我有一个三类:1.class Algorithm
,其中max()
在Collection
找到最大值:
public class Algorithm { public static <T extends Comparable> T max(Collection coll) { T max = coll.iterator().next(); for (T elm : coll) { if (max.compareTo(elm) < 0) max = elm; } return max; } }
2.Class Fruit
:
public class Fruit implements Comparable { private String name; private int size; public Fruit(String name, int size) { this.name = name; this.size = size; } public int compareTo(Fruit that) { if (size < that.size) return -1; else if (size == that.size) return 0; else return 1; } }
3.class Apple
扩展Fruit
:
public class Apple extends Fruit { public Apple(int size) { super("Apple", size); } }
现在的问题是:
public class Main { public static void main(String[] args) { Apple a1 = new Apple(10); Apple a2 = new Apple(34); List apples = Arrays.asList(a1, a2); System.out.println(Collections.max(apples).size); } }
根据这篇文章Java – 语法问题:我应该用这种方式编写它: public static <T extends Comparable> T max(Collection coll)
public static <T extends Comparable> T max(Collection coll)
。 但现在工作正常。为什么? Apple
类没有实现Comparable
并且没有super
。
[UPDATE]
Java Generics and Collections Book说:
如果没有
super
通配符,找到List
的最大值将是非法的,即使允许查找List
的最大值。
假设我们将max
方法更改为:
> T max(Collection extends T> coll)
你无法获得List
的max
,因为Apple
没有实现Comparable
,它实现了Comparable
。 但是你和我完全清楚, Apple
知道如何将自己与另一个Fruit
进行比较,因为它inheritance了这个function。
我们通过将max
的声明更改为此来解决问题:
> T max(Collection extends T> coll)
这意味着我们接受任何T
类,以便:
-
T implements Comparable
, 或者…… -
T implements Comparable
为某些X
T implements Comparable
,这样X
就是T
的超类
为了找到max
,我们必须确保T
任何实例都可以安全地接受另一个T
实例作为其compare
方法的参数。
在第一个场景中,很明显T
任何实例都可以安全地接受T
另一个实例作为其compare(T)
方法的参数。
在第二种情况下, T
任何实例都可以安全地接受另一个T
实例作为其compare(X)
方法的参数,因为T
所有实例也是X
实例。
您的示例说明了第二种情况,其中T
对应Apple
, X
对应Fruit
。
您使用Collections.max(apples)
而不是Algorithm.max
。
Collections.max
声明略有不同:
public static > T max(Collection extends T> coll)
很抱歉把它带回去,但我认为这很重要。 从Collections.max()更改为Algorithm.max()时,您的代码是否已停止正常工作? 我在jdk8中做了一个类似的测试,我不明白它为什么工作正常,而根据Java Generics和Collections它不应该。
我有一个Fruit抽象类(实现Comparable):
public abstract class Fruit implements Comparable { private String name; private int size; public Fruit(String name, int size) { this.name = name; this.size = size; } public int compareTo(Fruit that) { if (size < that.size) return -1; else if (size == that.size) return 0; else return 1; } }
然后我有一个Apple扩展Fruit类:
public class Apple extends Fruit { public Apple(String name, int size) { super(name, size); } }
最后:
public class GenericsTest { @Test public void test1() { final Apple a1 = new Apple("apple1", 50); final Apple a2 = new Apple("apple2", 70); final Apple a3 = new Apple("apple3", 34); final List apples = Lists.newArrayList(a1, a2, a3); System.out.println(GenericsTest.max(apples).getSize()); } private static > T max(Collection extends T> coll) { T max = coll.iterator().next(); for (T elm : coll) { if (max.compareTo(elm) < 0) max = elm; } return max; } }
代码工作,而没有? max方法签名中的super T和List属于Apple类型。 根据你提到的报价,它应该不起作用。 我好像在这里感到困惑......