Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
500 views
in Technique[技术] by (71.8m points)

java - Java 8中的::(双冒号)运算符(:: (double colon) operator in Java 8)

I was exploring the Java 8 source and found this particular part of code very surprising:

(我正在探索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;
}

Is Math::max something like a method pointer?

(Math::max是否类似于方法指针?)

How does a normal static method get converted to IntBinaryOperator ?

(普通的static方法如何转换为IntBinaryOperator ?)

  ask by Narendra Pathai translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Usually, one would call the reduce method using Math.max(int, int) as follows:

(通常,可以使用Math.max(int, int)调用reduce方法Math.max(int, int)如下所示:)

reduce(new IntBinaryOperator() {
    int applyAsInt(int left, int right) {
        return Math.max(left, right);
    }
});

That requires a lot of syntax for just calling Math.max .

(仅调用Math.max需要大量语法。)

That's where lambda expressions come into play.

(那就是lambda表达式起作用的地方。)

Since Java 8 it is allowed to do the same thing in a much shorter way:

(从Java 8开始,允许以更短的方式执行相同的操作:)

reduce((int left, int right) -> Math.max(left, right));

How does this work?

(这是如何运作的?)

The java compiler "detects", that you want to implement a method that accepts two int s and returns one int .

(Java编译器“检测”您要实现一个接受两个int并返回一个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).

(这等效于接口IntBinaryOperator唯一方法的形式参数(方法参数reduce您要调用)。)

So the compiler does the rest for you - it just assumes you want to implement IntBinaryOperator .

(因此,编译器会为您完成其余工作-只是假设您要实现IntBinaryOperator 。)

But as Math.max(int, int) itself fulfills the formal requirements of IntBinaryOperator , it can be used directly.

(但是由于Math.max(int, int)本身满足IntBinaryOperator的形式要求,因此可以直接使用它。)

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:

(由于Java 7没有任何语法允许将方法本身作为参数传递(您只能传递方法结果,而不能传递方法引用),因此Java 8中引入了::语法来引用方法:)

reduce(Math::max);

Note that this will be interpreted by the compiler, not by the JVM at runtime!

(注意,这将由编译器而不是运行时的JVM解释!)

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!

(尽管它为所有三个代码段生成了不同的字节码,但它们在语义上是相等的,因此后两个可以视为上述IntBinaryOperator实现的IntBinaryOperator版本(并且可能效率更高)!)

(See also Translation of Lambda Expressions )

((另请参见Lambda表达式的翻译 ))


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...