Lambda表达式底层运行原理

一、手动利用记事本编写Java测试代码

Lambda表达式底层运行原理_第1张图片

二、使用命令行进行编译

javac TestDemo.java

编译后会生成两个class文件

Lambda表达式底层运行原理_第2张图片

查看编译后的class文件

javap -p InterDemo.class

E:\test>javac TestDemo.java

E:\test>javap -p TestDemo.class
Compiled from "TestDemo.java"
public class TestDemo {
  public TestDemo();
  public static void main(java.lang.String[]);
  private static void lambda$main$0(java.lang.String);
}

这里可以看到有一个构造方法,一个main方法,还有一个私有的静态方法,这个静态方法只要你使用都会生成,是一样的。

这个静态私有方法就是Lambda表达式中的方法实现。也就是Lambda表达式在底层构建中生成了一个

private static void lambda$main$0(java.lang.String message){

System.out.println(message);

}

这个私有静态方法什么时候被调用了呐?

我们对它内部生成的所有接口的源代码进行一个输出,通过如下代码我们可以查看TestDemo底层详细的编译过程

E:\test>java -Djdk.internal.lambda.dumpProxyClasses TestDemo
WangJun

这时你会发现文件夹中会生成一个TestDemo$$Lambda$1.class文件

Lambda表达式底层运行原理_第3张图片

我们对该文件字节码文件进行一个查看

E:\test>javap -p TestDemo$$Lambda$1.class
final class TestDemo$$Lambda$1 implements InterDemo {
  private TestDemo$$Lambda$1();
  public void markUp(java.lang.String);
}

可以看出Lambda表达式在编译的时候第一个是生成了一个私有的静态方法Lambda$main。

另外就是在构建时生成了一个内部类型:TestDemo$$Lambda$1.class

在这里边可以看到第一个是一个构造方法,第二个markUp的实现实际上就是调用了上边的私有静态方法。在调用静态方法的过程中将message传递了过来。

public void markUp(java.lang.String message){

       TestDemo.lambda$main$0(message);

}

总结:

Lambda表达式在编译的过程中会生成一个私有的静态方法,在静态方法中做了一个方法的基本实现。

另外在编译的同时会针对Lambda表达式的目标接口,生成一个内部类型实现定义的接口,在实现这个接口的方法中完成对这个静态方法具体执行过程的调用

这两个方法在底层解析执行的时候其实他是在底层new 了一个当前内部类接口的对象,通过这个内部类接口的对象调用这个方法的marUp方法。

实际上Lambda表达式的运行过程可以理解为如下代码:

public class TestDemo{
	public static void main(String [] args){
		InterDemo inter=(string)->System.out.println(string);
		inter.markUp("WangJun");
		/**
			new TestDemo$$Lambda$1().markUp("WangJun");
		*/
	}
}
/**
public class TestDemo {
  public TestDemo();
  public static void main(java.lang.String[]);
  private static void lambda$main$0(java.lang.String){
	  System.out.println(message);
  }
}
*/
/**
final class TestDemo$$Lambda$1 implements InterDemo {
  private TestDemo$$Lambda$1();
  public void markUp(java.lang.String){
	  TestDemo.lambda$main$0(java.lang.String message){
		  TestDemo.lambda$main$0(message);
	  }
  }
}
*/
interface InterDemo{
	void markUp(String string);
}

Lambda表达式底层运行原理_第4张图片

你可能感兴趣的:(jdk8)