Java 8中使用非静态方法的lambda
我试图在新的Java 8中学习lambdas。有一件有趣的事情。 如果method与function接口具有相同的签名,则可以使用lambdas API将其分配给它。 例如。
Comparator myComp = Integer::compare;
这个方法(Integer.compare)是静态的,取两个值,一切都很完美。 签名与接口方法中的签名相同。 但是,例如,这可以用非静态方法来实现
Comparator myComp = Integer::compareTo.
此方法是非静态的(实例级别),此外,它只需要一个值。 据我所知,Java中没有非静态方法,每个方法都是静态的,但如果它没有标记为静态,则将其作为第一个参数。 如下
compareTo(this,Integer value).
假设由于比较对象和整数而导致结果未定义是合理的。 但是这个工作。
Comparator comparator = Integer::compareTo; Comparator comparator2 = Integer::compare; System.out.println(comparator.compare(1,2)); System.out.println(comparator2.compare(1,2));
这同样有效。 我调试了调用方法堆栈。 在没有创建实例的情况下调用比较器对象的方法比较时, 值已经由第一个参数初始化,当然这是对象的有效引用。
问题是这是如何工作的? 在调用方法编译器检查时,如果类只有一个字段与方法中的第一个param具有相同的类型,如果类有编译器隐含地创建具有初始化字段的类的新实例或者它是如何工作的?
这是因为lambdas不是来自面向对象的世界。
当您为Comparator
分配某个方法时,它的任务是执行比较。
Comparator methodOne = Integer::compare; Comparator methodTwo = Integer::compareTo;
这种方法一。比较methodOne.compare(1,2);
将被转换为Integer.compare(1,2)
它被称为非实例捕获并引用静态方法
这个方法methodTwo.compare(1,2);
将被转换为1.compareTo(2)
被称为实例捕获并引用实例方法。
编译器“知道”您引用了哪种类型的方法,因此它可以无错误地处理。
方法参考捕获