【发布时间】:2014-04-30 13:50:50
【问题描述】:
假设我有一个通用接口:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
还有一个方法sort:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
我可以调用此方法并将 lambda 表达式作为参数传递:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
这样就可以了。
但是现在如果我将接口设为非泛型,而将方法设为泛型:
interface MyComparable {
public <T extends Comparable<T>> int compare(T obj1, T obj2);
}
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable comp) {
}
然后像这样调用:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
它无法编译。它在 lambda 表达式中显示错误:
“目标方法是通用的”
好的,当我使用javac 编译它时,它显示以下错误:
SO.java:20: error: incompatible types: cannot infer type-variable(s) T#1
sort(list, (a, b) -> a.compareTo(b));
^
(argument mismatch; invalid functional descriptor for lambda expression
method <T#2>(T#2,T#2)int in interface MyComparable is generic)
where T#1,T#2 are type-variables:
T#1 extends Comparable<T#1> declared in method <T#1>sort(List<T#1>,MyComparable)
T#2 extends Comparable<T#2> declared in method <T#2>compare(T#2,T#2)
1 error
从这个错误消息中,编译器似乎无法推断类型参数。是这样吗?如果是,那为什么会这样呢?
我尝试了各种方法,通过互联网搜索。然后找到了this JavaCodeGeeks article,说明了一个办法,于是试了一下:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
这又是行不通的,这与那篇文章声称的行不通。可能它曾经在某些初始版本中工作。
所以我的问题是:有没有办法为泛型方法创建 lambda 表达式?不过,我可以通过创建方法来使用方法引用来做到这一点:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
在某些类中说SO,并将其传递为:
sort(list, SO::compare);
【问题讨论】:
标签: java generics lambda java-8