为什么Java-8 lambda需要invokeDynamic byteCode来调用接口方法

Sug*_*lai 4 java lambda java-8

您好我正在尝试理解使用Lambda表达式的优点,我听说JVM使用invokeDynamic byteCode来执行lambda表达式会提高性能相比XXXX(对不起,我不知道,它可能是一个匿名内部类) .

我的问题是为什么Lambda表达式需要invokeDynamic byteCode.

例如:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

lambda表达式(int a, int b) -> a + b;可以简单地用于静态方法

   private static int lambda$1(int a, int b) {
       return a + b;
   }
Run Code Online (Sandbox Code Playgroud)

最终可以使用invokstaticbyteCode 调用吗?

更多问题:什么是动态性lambda表达式试图实现,当所有参数类型,返回类型在编译时自己定义.

例如:在lambda表达式中,(int a, int b) -> a + b;everything(argument type, return type)在编译时自己定义了吗?

Hol*_*ger 11

保持lambda表达式的主体的方法不会被调用invokedynamic.invokeinterface与任何其他接口方法一样,通过调用函数接口的实现.调用者甚至不知道是否已为lambda表达式生成实现接口的对象.

这个生成的接口实现如何调用合成方法,是特定于JRE的,但通常是通过普通的调用(invokestatic,invokevirtualinvokespecial)来实现的.只有访问权限遵循不同的规则,即该方法可以由生成的类调用,尽管是private.

invokedynamic指令被用于实例化所述接口实现的,所以它允许任意的,未知的实现类,包括类,它们不在编译时存在,但在运行时产生的.它还可以返回现有实例而不是创建新实例,这对于普通实例创建代码是不可能的.