为什么我们不能捕获具有两个参数的方法的通配符?
Why can't we capture wildcards for the method with two parameters?
与 that 问题相关。
我知道通配符捕获。例如,以下可用于反转列表:
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));
}
}
现在我正在尝试为这种情况写同样的东西:
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);
}
我预计它也编译得很好。是否可以通过这种方式捕获具有两个或更多参数的方法的通配符?
因为,正如我在回答你的另一个问题时所说,编译器无法知道这两个 ?
代表相同的类型。
两个?
分别代表某种未知类型。 compare
方法需要两个 Comparable
相同类型的对象 T
。如果从 comp
方法中调用 compare
,编译器无法确定两个 ?
代表相同的类型。
在这个方法中
private <T> int comp(Comparable<T> upper, Comparable<T> lower){
return upper.compareTo((T) lower);
}
两个参数共享相同的类型参数。
同时,另一种方法并非如此:
private int compare (Comparable<?> upper, Comparable<?> lower){
return comp(upper, lower);
}
在这里,编译器没有证据表明 upper
和 lower
的类型参数是相同的,这就是拒绝为编译开绿灯的原因。
如果您希望这两种方法共享相同的类型参数,您可以将类型参数设置为 class-scoped。例如:
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);
}
}
另一种选择(如果您不喜欢第一个)是为 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);
}
此外,如果你想避免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);
}
}
与 that 问题相关。
我知道通配符捕获。例如,以下可用于反转列表:
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));
}
}
现在我正在尝试为这种情况写同样的东西:
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);
}
我预计它也编译得很好。是否可以通过这种方式捕获具有两个或更多参数的方法的通配符?
因为,正如我在回答你的另一个问题时所说,编译器无法知道这两个 ?
代表相同的类型。
两个?
分别代表某种未知类型。 compare
方法需要两个 Comparable
相同类型的对象 T
。如果从 comp
方法中调用 compare
,编译器无法确定两个 ?
代表相同的类型。
在这个方法中
private <T> int comp(Comparable<T> upper, Comparable<T> lower){
return upper.compareTo((T) lower);
}
两个参数共享相同的类型参数。
同时,另一种方法并非如此:
private int compare (Comparable<?> upper, Comparable<?> lower){
return comp(upper, lower);
}
在这里,编译器没有证据表明 upper
和 lower
的类型参数是相同的,这就是拒绝为编译开绿灯的原因。
如果您希望这两种方法共享相同的类型参数,您可以将类型参数设置为 class-scoped。例如:
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);
}
}
另一种选择(如果您不喜欢第一个)是为 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);
}
此外,如果你想避免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);
}
}