Lambda表达式和泛型方法 [英] Lambda Expression and generic method
问题描述
假设我有一个通用接口:
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){
//对列表进行排序
}
我可以调用这个方法并传递一个lambda表达式作为参数:
列表与LT;字符串> 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:错误:不兼容类型:无法推断类型变量T#1
sort(list,(a,b) - > a。的compareTo(b));
$
(参数不匹配;对于lambda表达式无效的函数描述符
method< T#2>(T#2,T#2)interface MyComparable中的int是泛型的)
其中T#1,T#2是类型变量:
T#1扩展了可比较的< T#1>在方法< T#1> sort(List< T#1>,MyComparable)
T#2 extends< T#2>在方法< T#2>中比较(T#2,T#2)
1错误
从这个错误消息看来,编译器似乎无法推断出类型参数。是这样吗?如果是的话,为什么会发生这种情况?
我尝试了各种方式,通过互联网搜索。然后我找到这篇JavaCodeGeeks文章,其中显示了所以我试过:
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);
$ / code>
在某些课程中说 SO
,并将其传递为:
sort(list,SO :: compare);
不能使用 lambda表达式如果功能接口中的方法具有类型参数,则功能接口 。请参阅JLS8中的第15.27.3节。 : b
$ b
如果 T
,lambda表达式与目标类型 T / em>是一个函数接口类型(第9.8节),表达式为一致,函数类型为[..] T. [..]一个lambda表达式一致如果以下全部为
true,则使用函数类型:
- 函数类型具有 no type parameters 。
- [..]
Suppose I've a generic interface:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
And a method sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
I can invoke this method and pass a lambda expression as argument:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
That will work fine.
But now if I make the interface non-generic, and the method generic:
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) {
}
And then invoke this like:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
It doesn't compile. It shows error at lambda expression saying:
"Target method is generic"
OK, when I compiled it using javac
, it shows following error:
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
From this error message, it seems like compiler is not able to infer the type arguments. Is that the case? If yes, then why is it happening like this?
I tried various ways, searched through the internet. Then I found this JavaCodeGeeks article, which shows a way, so I tried:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
which again doesn't work, contrary to what that article claims that it works. Might be possible that it used to work in some initial builds.
So my question is: Is there any way to create lambda expression for a generic method? I can do this using a method reference though, by creating a method:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
in some class say SO
, and pass it as:
sort(list, SO::compare);
You can't use a lambda expression for a functional interface, if the method in the functional interface has type parameters. See section §15.27.3 in JLS8:
A lambda expression is compatible [..] with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of [..] T. [..] A lambda expression is congruent with a function type if all of the following are true:
- The function type has no type parameters.
- [..]
这篇关于Lambda表达式和泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!