在方法类型参数列表或方法参数中定义有界类型参数

时间:2020-06-30 09:42:43

标签: java generics

以下两个方法定义之间有什么区别?如果它们相同,则首选哪一个?

public static <T extends Comparable<? super T>>
void sort1(List<T> list) {}

public static <T>
void sort2(List<? extends Comparable<? super T>> list) {}

如果方法中有多个使用类型参数的参数,那有什么区别?

public static <T extends Comparable<? super T>>
void add1(List<T> list, T element) {}

public static <T>
void add2(List<? extends Comparable<? super T>> list, T element) {}

1 个答案:

答案 0 :(得分:4)

这些不相同;对于类型系统,它们是不同的。 sort1接受类型变量List,而sort2接受通配符List。由于您正在执行 sort 操作,因此将修改传入的参数(List);您可能想在内部执行此操作,例如:

public static <T extends Comparable<? super T>> void sort1(List<T> list) {
    list.set(0, list.get(0));
}

public static <T> void sort2(List<? extends Comparable<? super T>> list) {
    list.set(0, list.get(0)); // does not compile
}

仅发现第二个将不会编译,因为它使用了wildcard(不过,有很多方法可以解决此问题)。

如果您尝试这样做,则在第二个示例中也会出现相同的情况:

public static <T> void add2(List<? extends Comparable<? super T>> list, T element) {
    list.add(element);
}

一般规则是,当您尝试修改时,您要坚持使用类型变量。如果您无法做到这一点,那么有多种方法可以解决它,例如wildcard capture