Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Java-8 lambda need invokeDynamic byteCode to invoke an interface method

Hi I am trying to understand the advantages of using Lambda expression, where I heard usage of the invokeDynamic byteCode by JVM to execute lambda expression will improve the performance compared to XXXX(Sorry I don't know, it might be an Anonymous inner class).

My question is Why Lambda expressions need invokeDynamic byteCode.

For example:

public class LambdaTest {
    public static void main(String[] args) {
        MathOperation addition = (int a, int b) -> a + b;
        addition.operation(1, 2);
    }

    private static int operate(int a, int b, MathOperation operation){
        return operation.operation(a, b);
    }

    interface MathOperation {
       int operation(int a, int b);
    }
}

where the lambda expression (int a, int b) -> a + b; can be simply desugared into a static method like

   private static int lambda$1(int a, int b) {
       return a + b;
   }

which eventually can be invoked using invokstatic byteCode right?

More questions: What is the dynamicity lambda expression trying to achieve, when all the argument type, returns type are defined during the compile time itself.

For example: in the lambda expression (int a, int b) -> a + b; everything(argument type, return type) got defined during the compile time itself right?

like image 682
Suganthan Madhavan Pillai Avatar asked Dec 18 '22 20:12

Suganthan Madhavan Pillai


1 Answers

The method holding the body of the lambda expression is not invoked via invokedynamic. The implementation of the functional interface is invoked via invokeinterface, just like any other interface method. The caller even doesn’t know whether an object implementing an interface has been generated for a lambda expression.

How this generated implementation of the interface invokes the synthetic method, is JRE specific, but usually it happens via an ordinary invocation (invokestatic, invokevirtual or invokespecial). Only the access rights follow different rules, i.e. the method can be invoked by the generated class despite being private.

The invokedynamic instruction is used for the instantiation of the interface implementation, so it allows arbitrary, unknown implementation classes, including classes, which do not exist at compile-time, but are generated at runtime. It also opens the possibility to return an existing instance instead of creating a new one, which is impossible for ordinary instance creation code.

like image 190
Holger Avatar answered Dec 21 '22 09:12

Holger