Java Collections.min/max方法的签名

Java Collections.min/max方法的签名,java,generics,wildcard,Java,Generics,Wildcard,在Java中,Collections类包含以下方法: public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c) public static这个?的一个好处是它禁止在集合中添加项目我认为它实际上没有为这个方法提供更多的东西,但是当t是类的一部分而不仅仅是静态方法时,这是一个好习惯 他们把它包括在这里,这样它就可以成为一个新的公约,在

在Java中,Collections类包含以下方法:

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)

public static这个
的一个好处是它禁止在
集合中添加项目

我认为它实际上没有为这个方法提供更多的东西,但是当t是类的一部分而不仅仅是静态方法时,这是一个好习惯

他们把它包括在这里,这样它就可以成为一个新的公约,在这个公约中,每一个泛型都应该扩展到

T类应遵循PECS:


但是静态方法不需要(至少参数,返回值应该总是这样)

这是为了支持Java1.4(以及更早版本)中方法的遗留签名

在Java5之前,这些方法的签名是

public static Object min ( Collection c );
对于多个边界,擦除规则使第一个边界成为方法的原始类型,因此如果没有
对象&
,签名将是

public static Comparable min ( Collection c );
遗留代码将被破坏


这篇文章摘自O'Reilly的Java泛型和集合书籍,第3.6章,类型推断是一个棘手的话题,我承认我对它了解不多。但是,请检查此示例:

public class ScratchPad {
   private static class A implements Comparable<A> {
     public int compareTo(A o) { return 0; }
   }
   private static class B extends A {}
   private static class C extends B {}

   public static void main(String[] args)
   {
     Collection<C> coll = null;
     B b = Scratchpad.<B>min(coll);
   }

   public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)  {
     return null;
   }

   //public static <T extends Object & Comparable<? super T>> T min(Collection<T> c) {
   //  return null;
   //}
}
公共类草稿行{
私有静态类A实现了可比较的{
public int compareTo(ao){返回0;}
}
私有静态类B扩展了{}
私有静态类C扩展了B{}
公共静态void main(字符串[]args)
{
集合coll=null;
B=草稿行最小值(coll);
}

公共静态基于我对马克答案的评论,如果你有

class Play {
    class A implements Comparable<A> {
        @Override
        public int compareTo(A o) {
            return 0;
        }
    }

    class B extends A {
    }

    class C extends A {
    }

    public static <T extends Object & Comparable<? super T>> T min(
            Collection<? extends T> c) {
        Iterator<? extends T> i = c.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) < 0)
                candidate = next;
        }
        return candidate;
    }

    public static List<? extends A> getMixedList() {
        Play p = new Play();
        ArrayList<A> c = new ArrayList<A>();
        c.add(p.new C());
        c.add(p.new B());
        return c;
    }

    public static void main(String[] args) {
        ArrayList<A> c = new ArrayList<A>();
        Collection<? extends A> coll = getMixedList();
        A a = Play.min(coll);
    }
}
课堂游戏{
A级执行可比较的{
@凌驾
公共整数比较(AO){
返回0;
}
}
B类扩展了A类{
}
C类扩展了{
}

公共静态你能为我澄清一下吗?我也对这个问题感兴趣。这是真的,尽管我不会称之为好处,而且与问题无关。它承诺集合将保持不变,但限制仅适用于min/max函数本身。因为集合可能是t的任何集合类型集合,其中V是T的子类型,您永远无法确定是否向传入集合中添加了正确类型的对象。我认为您所说的适用于“extends object&…”部分,而问题是关于“?extends T”部分。我认为如果a、B和C都有compareTo的实现,这可能会很有用(每个类都覆盖了前面的“方法”。通过调用min(coll),你告诉它使用类B的compareTo,而不是类C的compareTo,后者可能会给出不同的顺序。我明白你的观点。但是,如果使用min的第二个签名,我就可以编写
B=Scratchpad.min(coll)
,它也会编译得很愉快(我想大概是这样)。但是你只是强迫这个错误发生。你能给出一个真实的例子,为什么你需要强迫它发生在
?实际上我是个笨蛋,它总是使用它在运行时类的层次结构中遇到的第一个方法,在本例中是C.compareTo。@frosty_hotboy:如果我正确理解你来自哪里,那么不,那不是情况并非如此。泛型对选择要运行的虚拟方法没有影响。如果C提供了compareTo(a)方法,则无论该方法的类型参数如何,都将始终使用该方法。如果C尝试实现Comparable,则会出现编译时错误,因为无法使用不同的参数实现同一接口两次。