Sunday, 10 December 2017

:: (double colon) operator in Java 8

itemprop="text">

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;

}


Is
Math::max something like a method pointer? How does a normal
static method get converted to
IntBinaryOperator?


class="post-text" itemprop="text">
class="normal">Answer



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);


}
});


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));


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.




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);


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!



(See also href="http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html"
rel="noreferrer">Translation of Lambda Expressions)



No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...