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").他们的方法标志不一样.
有关编译器为何生成此类代码的任何信息?
如果您正在尝试学习方法参考,您应该使用某种学习材料,例如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实现的两个实例.