::(双冒号)Java 8 中的运算符 [英] :: (double colon) operator in Java 8

查看:27
本文介绍了::(双冒号)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 ints 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 中的运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆