Lambda translation is a two step process, One: desugaring the lambda into a static method in same class.
public class Main {
public static void main(String[] args) {
Runnable r = () -> System.out.println("Hello");
System.out.println(Arrays.asList(Main.class.getDeclaredMethods()));
}
}
[private static void Main.lambda$main$0(), public static void Main.main(java.lang.String[])]
Two: generation of a class that implements the Functional Interface.
System.out.println("A class has been generated: " + r.getClass());
System.out.println("That implements a Functional Interface: " + Arrays.asList(r.getClass().getInterfaces()));
A class has been generated: class Main$$Lambda$1/149928006
That implements a Functional Interface: [interface java.lang.Runnable]
Question: What is the need of this static method? Why can't the lambda body be put directly into the interface method? Something like:
class Main$$Lambda$1 {
public void run() {
/* Lambda body here */
}
}
In addition to the correct answers given here (because the current scheme is more efficient, reducing capture/linkage costs for lambdas and reducing code duplication), there are a few other reasons why your idea simply doesn't make sense.
Because this way it's actually cheaper. Generating a lambda from the method on the fly during the first invocation is better than loading a separate class via class loader. Internally it uses UNSAFE.defineAnonymousClass
which is more light-weight class than normal. Such "lambda-class" is not bound to any class loader, so can be easily garbage-collected when it's no longer necessary. Also I guess there are plans to make this mechanism even more light-weight and faster. For normal anonymous class this would not be possible as from the point of JVM such classes don't differ from usual classes and much more heavy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With