Java 8中使用非静态方法的lambda

9 java lambda java-8

我试图在新的Java 8中学习lambdas.有一件有趣的事情.如果方法与功能接口具有相同的签名,则可以使用lambdas API将其分配给它.例如.

Comparator<Integer> myComp = Integer::compare;
Run Code Online (Sandbox Code Playgroud)

这个方法(Integer.compare)是静态的,取两个值,一切都很完美.签名与接口方法中的签名相同.例如,这可以用非静态方法制作

Comparator<Integer> myComp = Integer::compareTo.
Run Code Online (Sandbox Code Playgroud)

此方法是非静态的(实例级别),此外,它只需要一个值.据我所知,Java中没有非静态方法,每个方法都是静态的,但如果它没有标记为静态,则它this作为第一个参数.如下

compareTo(this,Integer value).
Run Code Online (Sandbox Code Playgroud)

假设由于比较对象和整数而导致结果未定义是合理的.但是这个工作.

Comparator<Integer> comparator = Integer::compareTo;
Comparator<Integer> comparator2 = Integer::compare;
System.out.println(comparator.compare(1,2));
System.out.println(comparator2.compare(1,2));
Run Code Online (Sandbox Code Playgroud)

这同样有效.我调试了调用方法堆栈.在不创建实例的情况下调用比较器对象的方法比较,this.值已经由第一个参数初始化,当然这是对象的有效引用.

所以问题是这是如何工作的?在调用方法编译器检查时,如果该类只有一个字段与方法中的第一个param具有相同的类型,那么如果类具有编译器,则隐含地创建具有初始化字段的类的新实例或者它是如何工作的?

Dam*_*ash 10

这是因为lambdas不是来自面向对象的世界.

当你为Comparator<Integer>它分配一些方法时,任务就是执行比较.

Comparator<Integer> methodOne = Integer::compare;
Comparator<Integer> methodTwo = Integer::compareTo;
Run Code Online (Sandbox Code Playgroud)

methodOne.compare(1,2);将被转换Integer.compare(1,2)为非实例捕获并引用静态方法

methodTwo.compare(1,2);将被转换1.compareTo(2)为被称为实例捕获并引用实例方法.

编译器"知道"您引用了哪种类型的方法,因此它可以无错误地处理.

方法参考捕获