我正在审查JDK类的源代码。
以下方法签名使我感到困惑:
public static <T extends Comparable<? super T>> void sort(List<T> list);由于该方法不返回任何内容,那么所有的形式类型参数是什么?
如果该方法的签名仅为以下内容,其行为将如何改变:
public static void sort(List<T> list);发布于 2015-05-06 09:07:31
语法:
public static void sort(List<T> list);是不合法的,因为T没有被声明。语法正确的最接近的代码是:
public static void sort(List<?> list);这意味着该方法将接受任何类型的列表,但要对列表进行排序,必须有一些方法来比较其元素--因此产生了原始签名:
public static <T extends Comparable<? super T>> void sort(List<T> list);这意味着可以通过compareTo()方法将每个元素与其他元素进行比较。
语法:
void sort(List<? extends Comparable> list)没有那么有用--它只是要求列表包含类似的对象,,但不一定是彼此的。例如,list可以包含一个字符串和一个Integer,这两个字符串是可比较的,但不是彼此的--您不能对这样的列表进行有意义的排序。这是因为未知类型对于每个元素都是不同的。但是,通过键入该方法,该类型仍然可以是任何类型,但对于列表中的所有元素,它都是相同的类型。
发布于 2015-05-06 09:03:25
如果是
public static void sort(List<T> list);Java将不知道应该从参数中推断出T类型。它会查找名为T的具体类或接口,找不到类或接口,并向您吐出编译器错误。
发布于 2015-05-06 21:23:23
塞拉和贝茨SCJP:
泛型方法最奇怪的一点是,必须在方法的返回类型之前声明类型变量。
就像其他人说的,唯一的方法是
public static void sort(List<T> list);要工作,实际上有一个名为T的类,在这种情况下,参数就像变量的其他类型声明一样。
这也可以帮助我们考虑效仿塞拉和贝茨的做法。这表明形式类型参数是为了避免命名冲突。
class X { public <X> X(X x) {} } 是的,这很管用..。类名、类型参数占位符和变量标识符之间没有命名冲突。
那我们还有另外一个案子:
void sort(List<? extends Comparable> list)这个案例被称为捕获通配符。编译器从通配符中获取类型规范并创建匿名类型。其效果与显式类型规范相同,只是该类型不能用于方法实现。您可以将其想象为以下伪代码:
<T_?001> void sort_?001(List<T_?001> list)本例展示了形式参数的另一个目标--它们允许在方法实现中使用命名类型。
<T extends Comparable> void sort(List<T> list) {
Iterator<T> it = list.iterator();
}https://stackoverflow.com/questions/30072110
复制相似问题