Java Lambda表达式

Java Lambda表达式,java,lambda,java-8,method-reference,Java,Lambda,Java 8,Method Reference,我目前正在学习JDK1.8上的lambda表达式。我遇到了一些我发现不懂的代码 代码如下: import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.lang.Comparable; /** * Hello world! * */ public class App { public static void main( String[] args ) throws

我目前正在学习JDK1.8上的lambda表达式。我遇到了一些我发现不懂的代码

代码如下:

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.lang.Comparable;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args ) throws Exception
    {

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

    }

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

        int n = comp.compare("5","2");
        System.out.println(n);
    }

}
我已经创建了这样一个方法,它是有效的。我不明白为什么java编译器调用
“5”。比较(“2”)
。他们的方法意义不一样


关于编译器为何生成此类代码的任何信息

如果你试图学习方法参考,你应该求助于某种学习材料,例如。你会发现:

方法引用的种类 榜样

  • 对包含Class::staticMethodName的静态方法的引用
  • 对特定对象的实例方法的引用
    包含object::instanceMethodName
  • 对特定类型的任意对象的实例方法的引用
    ContainingType::methodName
  • 对构造函数的引用
    ClassName::new
因此,您可以看到,方法引用并不局限于
static
方法

方法引用
Comparable::compareTo
与“对特定类型的任意对象的实例方法的引用”匹配

此时值得注意的是,您实际上是在引用方法
Comparable.compareTo
,就好像您编写了
Comparable::compareTo
。由于引用的方法本身没有类型参数,因此类型参数无效。例如,您可以编写具有相同结果的
Comparable::compareTo

所引用的方法具有功能签名<代码>(可比,可比)→ int,因为调用
compariable时,它会消耗两个
compariable
。在一个
compariable
上比较到
,将第二个
compariable
作为参数传递(它将返回一个
int
)。这与
界面的功能签名相匹配

interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}
接口MyComparable{
公共整数比较(T obj1,T obj2);
}
因此,方法引用可以在这个上下文中使用


我简化了功能签名;实际上它们是
(T,T)→int
使用
,因此,使用此函数只能比较同一具体
可比较的
实现的两个实例。

因此,您想知道如何将签名不同于预期的方法引用作为lambda表达式发送。但它们不需要完全相同。基本上,只有参数和返回类型的列表是重要的:

如果满足以下所有条件,则可以将lambda表达式指定给目标类型T:

  • T是一种功能接口类型

  • lambda表达式与T的方法具有相同数量的参数,并且这些参数的类型相同

  • lambda主体返回的每个表达式都与T的方法的返回类型兼容

  • lambda主体抛出的每个异常都是T的方法的throws子句所允许的


您的
compare()
String
String
)的参数列表可以与
String#compareTo()
this
String
)的参数列表相匹配,并且它们的返回类型也相同(
int
),因此当需要另一个参数时,一个参数可以用作lambda。

我调试了代码,并且创建了一个类型为App$$Lambda$1的类。您的
sort()
方法代表什么?名称“sort()”并不重要。我选择任何方法名称来学习和理解lamdas和方法引用。你可以用你想要的任何东西替换方法名“sort”。主要的问题是为什么int n=comp.compare(“5”,“2”)行可以工作。这是一种非常糟糕的样式。请将main声明为抛出异常。谢谢你的回答。谢谢你的回答。
interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}