为什么我们不能使用两个参数捕获方法的通配符?

use*_*882 6 java generics wildcard

问题有关.

我知道通配符捕获.例如,以下内容可用于反转列表:

public static void reverse(List<?> list) { rev(list); } //capturing the wildcard
private static <T> void rev(List<T> list) {
    List<T> tmp = new ArrayList<T>(list);
    for (int i = 0; i < list.size(); i++) {
        list.set(i, tmp.get(list.size()-i-1));
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试为这种情况编写相同的东西:

private int compare (Comparable<?> upper, Comparable<?> lower){
    return comp(upper, lower);  //The method comp(Comparable<T>, Comparable<T>) is not applicable for the arguments (Comparable<capture#5-of ?>, Comparable<capture#6-of ?>)
}

private <T> int comp(Comparable<T> upper, Comparable<T> lower){
    return upper.compareTo((T) lower);
}
Run Code Online (Sandbox Code Playgroud)

我希望它编译得很好.是否有可能捕获具有两个或更多参数的方法的wildacrds?

Kon*_*kov 2

在这个方法中

private <T> int comp(Comparable<T> upper, Comparable<T> lower){
    return upper.compareTo((T) lower);
}
Run Code Online (Sandbox Code Playgroud)

这两个参数共享相同的类型参数。

与此同时,另一种方法则不然:

private int compare (Comparable<?> upper, Comparable<?> lower){
    return comp(upper, lower); 
}
Run Code Online (Sandbox Code Playgroud)

upper在这里,编译器没有证据表明 和的类型参数lower相同,这就是为什么拒绝给编译开绿灯的原因。

如果您希望这两个方法共享相同的类型参数,则可以将类型参数设置为类范围。例如:

public class YourClass<T> {
     private int comp(Comparable<T> upper, Comparable<T> lower){
         return upper.compareTo((T) lower);
     }

     private int compare (Comparable<T> upper, Comparable<T> lower){
         return comp(upper, lower); 
     }
}
Run Code Online (Sandbox Code Playgroud)

comp()另一种选择(如果您不喜欢第一个)是为和的类型参数引入一个相同的上限compare()。例如:

private <T extends SomeSuperClass> int comp(Comparable<T> upper, Comparable<T> lower){
    return upper.compareTo((T) lower);
}

private <T extends SomeSuperClass> int compare (Comparable<T> upper, Comparable<T> lower){
    return comp(upper, lower); 
}
Run Code Online (Sandbox Code Playgroud)

此外,如果你想避免comp()方法中的强制转换,你可以这样做:

public class YourClass<T extends SomeSuperClass & Comparable<T>> {
     private int comp(T upper, T lower){
         return upper.compareTo(lower);
     }

     private int compare (T upper, T lower){
         return comp(upper, lower); 
     }
}
Run Code Online (Sandbox Code Playgroud)