【问题标题】:How do I reference the class of classes identified using the wildcard in Java?如何引用 Java 中使用通配符标识的类的类?
【发布时间】:2018-03-06 17:01:41
【问题描述】:

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

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,但这并不好,因为我必须在之后进行类型检查以确保一切安全。

【问题讨论】:

标签: java class generics wildcard


【解决方案1】:

你可以预先给出类型,然后使用它:

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);
    }
}

更多内容请参阅泛型教程的bounded section

作为user7 points out,我们也想在Comparable 上设置边界:

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

【讨论】:

  • (在这种特殊情况下,我可能应该使用E 而不是T,这是列表元素的标准...)
  • 如果你只有Comparable(原始类型),你会收到一个未经检查的警告——最好有Comparable&lt;E&gt;Comparable&lt;? super E&gt;
  • @user7:确实,我没有解决所有问题。我可能应该有。
【解决方案2】:

你可以使用有界类型参数

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);
    }

【讨论】:

    【解决方案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.

    【讨论】:

    • 你说得对,E 在这种情况下是更典型的类型名称,而不是 T
    • @AndyTurner 对,我从 OP 的代码中复制了这一部分。现在已修复。
    猜你喜欢
    • 2010-09-13
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多