To support functional programming, Java 8 introduces lambda expressions, so how do you implement lambda expressions in Java 8? What does a lambda expression produce after it is compiled? Before we go into the deep analysis, let's think about that each lambda expression in Java 8 must have a functional interface that corresponds to the difference between a functional interface and a normal interface, which can refer to the previous content, So you might think that lambda expressions are converted into an implementation class of the corresponding functional interface, and then invoke the implementation of subclasses in polymorphic ways, as the following code is a sample of a lambda expression
@FunctionalInterface
interface print<t> {public
void Print (T x);
}
public class Lambda {public
static void Printstring (String s, print<string> Print) {
print.print (s);
} Public
static void Main (string[] args) {
printstring ("Test", (x)-> System.out.println (x));
}
According to the above analysis, in theory after the compiler processing, the final generated code should be as shown below:
@FunctionalInterface
interface print<t> {public
void Print (T x);
}
Class Lambda$$0 implements print<string> {
@Override public
void Print (String x) {
SYSTEM.OUT.PRINTLN (x);
}
}
public class Lambda {public
static void Printstring (String s,
print<string> Print) {
Print.print (s);
}
public static void Main (string[] args) {
printstring ("Test", New lambda$$0 ());
}
or an internal class implementation, the code looks like this:
@FunctionalInterface
interface print<t> {public
void Print (T x);
}
public class Lambda {
final class Lambda$$0 implements print<string> {
@Override public
void Print ( String x) {
System.out.println (x);
}
}
public static void Printstring (String s,
print<string> Print) {
print.print (s);
}
public static void Main (string[] args) {
printstring ("Test", New Lambda (). New lambda$$0 ());
}
XOR, or this anonymous inner class implementation, the code looks like this:
@FunctionalInterface
interface print<t> {public
void Print (T x);
}
public class Lambda {public
static void Printstring (String s,
print<string> Print) {
print.print (s);
}
public static void Main (string[] args) {
printstring ("Test", new Print<string> () {
@Override
public void print (String x) {
System.out.println (x);
}}
);
}
The code above, in addition to the length of the code, is the same as the result of code implemented with a lambda expression, so how is Java 8 actually implemented? is not one of the above three implementations, you may feel that you are right, in fact, is right, in Java 8 in the internal class to implement lambda expression
So how does a lambda expression actually work?
To explore how lambda expressions are implemented, it is necessary to study the bytecode files that have been converted into lambda tables, which requires a byte-code viewing tool and a decompile tool in the JDK's Bin directory
Javap-p Lambda.class
The-p in the above command outputs all classes and members, and after running the above command, the results are as follows:
Compiled from ' Lambda.java ' public
class Lambda {public
lambda ();
public static void Printstring (Java.lang.String, print<java.lang.string>);
public static void Main (java.lang.string[]);
private static void Lambda$0 (java.lang.String);
}
The code above shows that the compiler will generate a private static function based on the lambda expression, and note that here is the build, not the equivalent
private static void Lambda$0 (java.lang.String);
To verify that the above conversion is correct? We define a function in the code that lambda$0 this, and the final code looks like this:
@FunctionalInterface
interface print<t> {public
void Print (T x);
}
public class Lambda {public
static void Printstring (String s,
print<string> Print) {
Print.print (s);
}
private static void Lambda$0 (String s) {
} public
static void Main (string[] args) {
printstring ("Test", X )-> System.out.println (x));
}
The code above does not have an error at compile time, but the runtime will complain because there are two lambda$0 functions, as shown below, are run-time errors
Exception in thread ' main ' Java.lang.ClassFormatError:Duplicate method Name&signature in class file Lambda at JAV A.lang.classloader.defineclass1 (Native method) at Java.lang.ClassLoader.defineClass (classloader.java:760) at Java. Security. Secureclassloader.defineclass (secureclassloader.java:142) at Java.net.URLClassLoader.defineClass ( urlclassloader.java:467) at java.net.urlclassloader.access$100 (urlclassloader.java:73) at java.net.URLClassLoader$ 1.run (urlclassloader.java:368) at Java.net.urlclassloader$1.run (urlclassloader.java:362) at Java.security.AccessCo Ntroller.doprivileged (Native method) at Java.net.URLClassLoader.findClass (urlclassloader.java:361) at Java.lang.Cl Assloader.loadclass (classloader.java:424) at Sun.misc.launcher$appclassloader.loadclass (Launcher.java:331) at Java . lang. Classloader.loadclass (classloader.java:357) at Sun.launcher.LauncherHelper.checkAndLoadMain (Launcherhelper.java : 495)
By JAVAP the above error code, the members of the output class after the decompile are shown below
Compiled from ' Lambda.java ' public
class Lambda {public
lambda ();
public static void Printstring (Java.lang.String, print<java.lang.string>);
private static void Lambda$0 (java.lang.String);
public static void Main (java.lang.string[]);
private static void Lambda$0 (java.lang.String);
}
<