The implementation of the so-called functional interface in Java 8 (with lambdas) or in Groovy (with closure) looks exactly the same, but the basic mechanisms are quite different. As an example, take the functional interface java.util.function.Consumer . We use it to call the new Java 8 forEach() method on a hypothetical java.util.List instance called myList .
In Java, it looks like this:
myList.forEach ((s) -> System.out.println(s));
Same thing in Groovy:
myList.forEach { s -> println s }
Both compilers generate new classes from lambda / closure code. The class generated by Java 8 implements the target interface ( Consumer in this case), not derived from anything, similar to a built-in anonymous class like this:
myList.forEach(new Consumer<Object>() { @Override public void accept (Object s) { System.out.println(s); } });
Unlike what Groovy generates, it looks something like this:
myList.forEach (new Closure(this) { void doCall(Object s) { println s } }
This creates an anonymous class derived from groovy.lang.Closure that does not implement any particular interface. However, it can be used here as a parameter. This is possible because Groovy creates a dynamic proxy object at runtime by implementing the Consumer interface and forwarding any calls to the generated Closure instance.
As a result, you can replace Java 8 lambdas with Groovy closure, but not vice versa. If you want to use the Groovy API in Java 8 code, you cannot call the Closure wait method with a lambda expression. Closure not a functional interface, but an abstract class, and it simply cannot be implemented using a lambda expression.
source share