我正在探索 Java 8 源代码,发现代码的这个特定部分非常令人惊讶:
// Defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(op));
}
@Override
public final OptionalInt max() {
return reduce(Math::max); // This is the gotcha line
}
// Defined in Math.java
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Math::max
类似于方法指针吗?普通的 static
方法如何转换为 IntBinaryOperator
?
原文由 Narendra Pathai 发布,翻译遵循 CC BY-SA 4.0 许可协议
通常,人们会使用
Math.max(int, int)
调用reduce
方法,如下所示:这需要很多语法来调用
Math.max
。这就是 lambda 表达式发挥作用的地方。从 Java 8 开始,它被允许以更短的方式做同样的事情:这是如何运作的? Java 编译器“检测”到您要实现一个接受两个
int
并返回一个int
的方法。这相当于接口唯一方法的形参IntBinaryOperator
(你要调用的方法的参数reduce
)。所以编译器会为您完成剩下的工作——它只是假设您要实现IntBinaryOperator
。但由于
Math.max(int, int)
本身满足IntBinaryOperator
的形式要求,可以直接使用。因为 Java 7 没有任何允许将方法本身作为参数传递的语法(您只能传递方法结果,而不能传递方法引用),Java 8 中引入了::
语法来引用方法:请注意,这将由编译器解释,而不是在运行时由 JVM 解释!尽管它为所有三个代码片段生成不同的字节码,但它们在语义上是相同的,所以最后两个可以被认为是上面
IntBinaryOperator
实现的简短(并且可能更有效)版本!(另请参阅 Lambda 表达式的翻译)