Java Lambda表达式

sho*_*odz -3 java lambda java-8 method-reference

我目前正在JDK 1.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);
    }

}
Run Code Online (Sandbox Code Playgroud)

comp.compare("5", "3")最终执行"5".compareTo("2").我的理解是编译器需要找到一个具有相同签名的静态方法

public <T extends Comparable<T>> int compare(T obj1, T obj2 );
Run Code Online (Sandbox Code Playgroud)

我创建了这样一个方法,它的工作原理.我不明白为什么java编译器调用"5".compareTo("2").他们的方法标志不一样.

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

Hol*_*ger 5

如果您正在尝试学习方法参考,您应该使用某种学习材料,例如Oracle的Java教程.在那里你会发现:

各种方法参考

       亲切的例子

  • 参考静态方法 ContainingClass::staticMethodName
  • 引用特定对象的实例方法 containingObject::instanceMethodName
  • 引用特定类型的任意对象的实例方法 ContainingType::methodName
  • 引用构造函数 ClassName::new

所以你看,方法引用不仅限于static方法.

您的方法引用Comparable::<String>compareTo匹配"对特定类型的任意对象的实例方法的引用"的类型.

在这一点上,值得注意的是,您实际上正在引用该方法Comparable.compareTo,就像您已经编写过一样Comparable::compareTo.由于引用的方法本身没有类型参数,因此类型参数无效.例如,你可以写Comparable::<Button>compareTo相同的结果.

引用的方法具有函数签名,(Comparable,Comparable) ? int因为它Comparable在调用Comparable.compareTo一个时消耗两个s Comparable,将第二个Comparable作为参数传递(并且它将返回一个int).这符合您的功能签名interface

interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}
Run Code Online (Sandbox Code Playgroud)

所以方法参考可以在这种情况下使用.

我简化了功能签名; 实际上它们正在(T,T)?int使用<T extends Comparable<T>>,因此您只能使用此函数比较同一具体Comparable实现的两个实例.