在下面的例子中,必须是"List <?extends T>",还是"List <T>"做同样的事情?

Oh *_*eah 0 java generics wildcard type-bounds

我明白那个

List<? extends T>
Run Code Online (Sandbox Code Playgroud)

允许列表是T(或T本身)的任何子类型,以及

List<T>
Run Code Online (Sandbox Code Playgroud)

只允许类型为T的列表.但是,请看下面的方法签名:

public static <T extends Object & Comparable<? super T>> T findMax(List<? extends T> myList, int begin, int end){
Run Code Online (Sandbox Code Playgroud)

以下课程:

public class ClassA{

}
public class ClassB extends ClassA implements Comparable<ClassA>{
public int compareTo(ClassA s){
    //do comparison
}
}
public class ClassC extends ClassB{

}
Run Code Online (Sandbox Code Playgroud)

假设T是ClassB,我想为我的列表传递一个T(ClassC)的子类型:

public static void main(String[] args){
    List<ClassC> myC = new ArrayList<ClassC>();
    ClassC a = findMax(myC, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,java如何推断T是ClassB,而不是ClassC?如果它无法推断ClassB(实际上推断出ClassC),那么下面的方法签名(没有"List")是否相同?

public static <T extends Object & Comparable<? super T>> T findMax(List<T> myList, int begin, int end){
Run Code Online (Sandbox Code Playgroud)

谢谢,杰克

Boh*_*ian 5

首先,? extends Object没有添加任何值,因为一切都扩展了Object,所以这两个方法是等价的:

public static <T extends Object & Comparable<? super T>> T findMax(List<T> myList, int begin, int end)
public static <T extends Comparable<? super T>> T findMax(List<T> myList, int begin, int end)
Run Code Online (Sandbox Code Playgroud)

简化后,您的问题基本上是等效的:

public static <T extends Comparable<? super T>> T findMax(List<T> myList, int begin, int end)
public static <T extends Comparable<? super T>> T findMax(List<? extends T> myList, int begin, int end)
Run Code Online (Sandbox Code Playgroud)

他们是不一样的.

原因是,使用第二种方法,您可以传入一个类型为返回类型的子类的List,而在第一种方法中,List的类型必须与返回的类型相同.