:: (double colon) operator in Java 8(Java 8 中的 ::(双冒号)运算符)
问题描述
我正在探索 Java 8 源代码,发现这部分代码非常令人惊讶:
I was exploring the Java 8 source and found this particular part of code very surprising:
//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
的?
Is Math::max
something like a method pointer?
How does a normal static
method gets converted to IntBinaryOperator
?
推荐答案
通常会使用 Math.max(int, int)
调用 reduce
方法,如下所示:
Usually, one would call the reduce
method using Math.max(int, int)
as follows:
reduce(new IntBinaryOperator() {
int applyAsInt(int left, int right) {
return Math.max(left, right);
}
});
仅调用 Math.max
就需要大量语法.这就是 lambda 表达式发挥作用的地方.从 Java 8 开始,它允许以更短的方式做同样的事情:
That requires a lot of syntax for just calling Math.max
. That's where lambda expressions come into play. Since Java 8 it is allowed to do the same thing in a much shorter way:
reduce((int left, int right) -> Math.max(left, right));
这是如何工作的?Java 编译器检测到"您想要实现一个接受两个 int
并返回一个 int
的方法.这相当于接口IntBinaryOperator
的唯一方法的形参(你要调用的方法reduce
的参数).所以编译器会为你完成剩下的工作——它只是假设你想要实现 IntBinaryOperator
.
How does this work? The java compiler "detects", that you want to implement a method that accepts two int
s and returns one int
. This is equivalent to the formal parameters of the one and only method of interface IntBinaryOperator
(the parameter of method reduce
you want to call). So the compiler does the rest for you - it just assumes you want to implement IntBinaryOperator
.
但是由于Math.max(int, int)
本身就满足IntBinaryOperator
的形式要求,所以可以直接使用.因为 Java 7 没有任何语法允许将方法本身作为参数传递(您只能传递方法结果,但不能传递方法引用),Java 8 中引入了 ::
语法参考方法:
But as Math.max(int, int)
itself fulfills the formal requirements of IntBinaryOperator
, it can be used directly. Because Java 7 does not have any syntax that allows a method itself to be passed as an argument (you can only pass method results, but never method references), the ::
syntax was introduced in Java 8 to reference methods:
reduce(Math::max);
请注意,这将由编译器解释,而不是在运行时由 JVM 解释!尽管它为所有三个代码片段生成不同的字节码,但它们在语义上是相等的,因此最后两个可以被认为是上述 IntBinaryOperator
实现的简短(并且可能更有效)版本!
Note that this will be interpreted by the compiler, not by the JVM at runtime! Although it produces different bytecodes for all three code snippets, they are semantically equal, so the last two can be considered to be short (and probably more efficient) versions of the IntBinaryOperator
implementation above!
(另请参见Lambda 表达式的翻译)
这篇关于Java 8 中的 ::(双冒号)运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java 8 中的 ::(双冒号)运算符
基础教程推荐
- 如何强制对超级方法进行多态调用? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01