仅在方法中定义的 Lambda 表达式和泛型 [英] Lambda Expression and generic defined only in method

查看:31
本文介绍了仅在方法中定义的 Lambda 表达式和泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个通用接口:

Suppose I've a generic interface:

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 表达式作为参数:

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

那会工作得很好.

但是现在如果我使接口非通用,并且方法通用:

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

然后像这样调用:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

它不会编译.它在 lambda 表达式中显示错误说:

It doesn't compile. It shows error at lambda expression saying:

目标方法是通用的"

好的,当我使用javac编译它时,它显示以下错误:

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?

我尝试了各种方法,通过互联网搜索.然后我找到了这篇 JavaCodeGeeks 文章,其中展示了一个方式,所以我试过:

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.

所以我的问题是:有没有办法为泛型方法创建 lambda 表达式?我可以使用方法引用来做到这一点,通过创建一个方法:

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

在某些类中说SO,并将其传递为:

in some class say SO, and pass it as:

sort(list, SO::compare);

推荐答案

如果函数式接口中的方法,则不能使用lambda表达式em>函数式接口有类型参数.请参阅JLS8 中的第 15.27.3 节:

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:

如果 T 是函数接口类型(第 9.8 节)并且表达式 一致,则 lambda 表达式与目标类型 T 兼容 [..] 函数类型为 [..] T. [..] 如果满足以下所有条件,则 lambda 表达式与函数类型一致真的:

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:

  • 函数类型没有类型参数.
  • [..]

这篇关于仅在方法中定义的 Lambda 表达式和泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆