2016-01-23 50 views
3

您好我想了解使用Lambda表達式的優勢,其中我聽說JVM使用invokeDynamic byteCode來執行lambda表達式將提高與XXXX相比的性能(對不起,我不知道,它可能是一個匿名內部類)。爲什麼Java-8 lambda需要invokeDynamic byteCode來調用接口方法

我的問題是爲什麼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); 
    } 
} 

其中λ表達式(int a, int b) -> a + b;可以簡單地脫糖到像

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

一個靜態方法,其最終可使用invokstatic的byteCode右被調用?

更多問題:什麼是lambda表達式嘗試實現的動態性,當所有參數類型返回類型都是在編譯時自身定義的。

例如:在lambda表達式(int a, int b) -> a + b;的一切(argument type, return type)在編譯時自己定義了吧?

回答

8

保存拉姆達表達式主體的方法是而不是通過invokedynamic調用。功能接口的實現通過invokeinterface調用,就像任何其他接口方法一樣。調用者甚至不知道是否爲lambda表達式生成了實現接口的對象。

這個生成的接口實現如何調用合成方法,是JRE特有的,但通常通過普通的調用(invokestatic,invokevirtualinvokespecial)發生。只有訪問權限遵循不同的規則,即儘管是private,該方法仍可由生成的類調用。

invokedynamic的指令被用於接口實現的實例,所以它允許任意的,未知的實現類,包括類,它們不在編譯時存在,但在運行時產生的。它還打開了返回現有實例而不是創建新實例的可能性,這對於普通實例創建代碼來說是不可能的。

相關問題