如何在Java中引用使用通配符标识的类的类?

时间:2018-03-06 17:01:41

标签: java class generics wildcard

例如,假设我想编写一个方法来切换列表的前两个元素,但前提是第二个元素大于第一个元素。我最初尝试做类似的事情:

static void swapFirstTwo(List<? extends Comparable> list) {
    if(list.get(0).compareTo(list.get(1)) > 0) {
        ? temp = list.get(0);
        list.set(0, list.get(1));
        list.set(1, temp);
    }
}

显然这不起作用,但我该怎么做呢?我可以用?替换Object,但那不好,因为我之后必须进行类型检查以确保一切都安全。

3 个答案:

答案 0 :(得分:5)

您可以预先提供类型,然后使用它:

static <T extends Comparable> void swapFirstTwo(List<T> list) {
// ----^^^^^^^^^^^^^^^^^^^^^^------------------------^
    if(list.get(0).compareTo(list.get(1)) > 0) {
        T temp = list.get(0);
// -----^
        list.set(0, list.get(1));
        list.set(1, temp);
    }
}

更多内容在Generics教程的bounded section中。

作为user7 points out,我们也希望将约束放在Comparable上:

static <T extends Comparable<T>> void swapFirstTwo(List<T> list) {
// -------------------------^^^

答案 1 :(得分:3)

您无法使用未命名的捕获来声明新变量,您可以捕获类型:

static <E extends Comparable<E>> void swapFirstTwo(List<E> list) {
    if(list.get(0).compareTo(list.get(1)) > 0) {
        E temp = list.get(0);
        list.set(0, list.get(1));
        list.set(1, temp);
    }
}

List<String> list = new ArrayList<>();
list.add("world");
list.add("hello");
System.out.println(list.get(0)+" "+list.get(1)); // world hello
swapFirstTwo(list);
System.out.println(list.get(0)+" "+list.get(1)); // hello world

Demo.

答案 2 :(得分:3)

您可以使用有界类型参数

static <E extends Comparable<? super E>> void swapFirstTwo(List<E> list) {
    if(list.get(0).compareTo(list.get(1)) > 0) {
        E temp = list.get(0);
        list.set(0, list.get(1));
        list.set(1, temp);
    }