Java8 函数式编程 Lambda表达式是怎么执行的?

Java8 函数式编程 Lambda表达式是怎么执行的?

public static <T> void useConsumer(Consumer<T> consumer, T t) {
    consumer.accept(t);
    consumer.accept(t);
}

@Test
public void lambadaTest_02() {
    useConsumer(System.out::println, "Hello World!");
}

想问下这段代码是怎么运行的!初入lambda表达式还不清楚,希望大佬带我入门

代码运行,会输出两段Hello World

阅读 1.7k
1 个回答

如果对你的Java类生成的class进行反编译的话

$ javap -l -c -s Functional.class 

将会得出如下结果:

Compiled from "Functional.java"
public class debug.test.Functional {
  public debug.test.Functional();
    descriptor: ()V
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
    LineNumberTable:
      line 7: 0
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       5     0  this   Ldebug/test/Functional;

  public static <T> void useConsumer(java.util.function.Consumer<T>, T);
    descriptor: (Ljava/util/function/Consumer;Ljava/lang/Object;)V
    Code:
       0: aload_0
       1: aload_1
       2: invokeinterface #2,  2            // InterfaceMethod java/util/function/Consumer.accept:(Ljava/lang/Object;)V
       7: aload_0
       8: aload_1
       9: invokeinterface #2,  2            // InterfaceMethod java/util/function/Consumer.accept:(Ljava/lang/Object;)V
      14: return
    LineNumberTable:
      line 10: 0
      line 11: 7
      line 12: 14
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      15     0 consumer   Ljava/util/function/Consumer;
          0      15     1     t   Ljava/lang/Object;

  public void lambadaTest_02();
    descriptor: ()V
    Code:
       0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: dup
       4: invokestatic  #4                  // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
       7: pop
       8: invokedynamic #5,  0              // InvokeDynamic #0:accept:(Ljava/io/PrintStream;)Ljava/util/function/Consumer;
      13: ldc           #6                  // String Hello World!
      15: invokestatic  #7                  // Method useConsumer:(Ljava/util/function/Consumer;Ljava/lang/Object;)V
      18: return
    LineNumberTable:
      line 16: 0
      line 17: 18
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      19     0  this   Ldebug/test/Functional;
}

上面最核心一条指令是invokedynamic. 这条指令允许你把System.out.println看成是Consumer接口的accept。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进