:: (Double Colon) Operator in Java 8

double colon assignment on method with two parameters

from https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html and https://www.codementor.io/eh3rrera/tutorials/using-java-8-method-reference-du10866vx

There would be 4 different kinds of method references. The corresponding lambda and method reference:

  • (args) -> Class.staticMethod(args), Class::staticMethod
  • (obj, args) -> obj.instanceMethod(args), ObjectType::instanceMethod
  • (args) -> obj.instanceMethod(args), obj::instanceMethod
  • (args) -> new ClassName(args), ClassName::new

The lambda value -> model.setA(CONSTANT, value) does not correspond with any of the lambdas above, so it is not possible to rewrite it as a method reference.

:: (double colon) operator in Java 8

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 Translation of Lambda Expressions)

Double colon operator not working with Java

A method reference is not the same as a method call. Those are two distinct things.

  • A method call is a standalone expression, or, more precisely, an expression statement. That means that in your case implementation2.sendNotification() works, as you would expect.

  • A method reference, however,

    is used to refer to the invocation of a method without actually performing the invocation

    and is not a standalone expression. It can only be used where a lambda expression can also be used. A method reference as a standalone expression does not compile, just like an arithmetic expression without assignment (e.g. 3 + 17;). This is enforced by the Java Language Specification, § 14.8 and § 15.13.


More to read:

  • Please Explain Java 8 Method Reference to instance Method using class name
  • Method reference in Java 8

Double Colon lambda for two levels method invocation

What you are expecting is called chaining. Method references does not support chaining.

Read more about Method References.

how can I replace java code that has double colon

The pre-Java 8 version would conventionally use an anonymous class like this:

grid.addColumn(new ValueProvider<Person, String>() {
@Override
public String apply(Person person) {
return person.getLastName();
}
})

But you don't need that to customize the method call. An ordinary lambda will do:

grid.addColumn(person -> person.getLastName(foo))

As you see, the latter is much more concise. Vaadin's API has been designed to embrace Java 8 features such as functional references, lambdas and streams. JDK8 and newer is also a requirement for modern Vaadin versions to function.



Related Topics



Leave a reply



Submit