How will Java lambda functions be compiled?

前端 未结 2 997
一向
一向 2020-11-22 12:24
Loop.times(5, () -> {
   System.out.println(\"looping\");
});

Which of these would it effectively compile to?

for(int i = 0; i &         


        
2条回答
  •  青春惊慌失措
    2020-11-22 12:52

    Java compiler will generate synthetic methods for the code construct that is neither explicitly nor implicitly declared.

    As we are aware, lambda expression/function is an anonymous class method implementation for abstract method in functional interface and if we see the byte code of a compiled class file with lambda expression, Instead of creating a new object that will wrap the Lambda function, it uses the new INVOKEDYNAMIC instruction to dynamically link this call site to the actual Lambda function which is converted to private static synthetic lambda$0(Ljava/lang/String;)V which will accept string as a parameter.

    private static synthetic lambda$0(Ljava/lang/String;)V
    GETSTAIC java/lang/System.out: Ljava/io/PrintStream;
    ALOAD 0
    INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V
    RETURN
    

    Example: list.forEach(x-> System.out.println(x));

    This lambda expression x-> System.out.println(x) is converted to private static synthetic block as mentioned above. But how this will be invoked for each element in the list when we run java Class? Refer the below byte code of lambda expression linkage as forEach accepts Consumer functional interface object.

    INVOKEDYNAMIC accept()Ljava/util/function/Consumer;
    [
    java/lang/invoke/LambdaMetaFactory.metafactory(Ljava/lang/invokeMethodHandler$Lookup.Ljava/lang/invoke/CallSite..
    //arguments
    (Ljava/lang/Object;)V
    //INVOKESTATIC
    com/.lambda$)(Ljava/lang/String;)V,
    (Ljava/lang/String;)V
    ]
    

    java.lang.invoke.LambdaMetaFactory: This class provides two forms of linkage methods:

    1. A standard version (metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)) using an optimized protocol,
    2. An alternate version altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)).

    These linkage methods are designed to support the evaluation of lambda expressions and method references in the Java Language. For every lambda expressions or method reference in the source code, there is a target type which is a functional interface. Evaluating a lambda expression produces an object of its target type. The recommended mechanism for evaluating lambda expressions is to desugar the lambda body to a method, invoke an invokedynamic call site whose static argument list describes the sole method of the functional interface and the desugared implementation method, and returns an object (the lambda object) that implements the target type. Note(For method references, the implementation method is simply the referenced method; no desugaring is needed.)

提交回复
热议问题