Lambda 和記憶體利用率

由於 Java lambda 是閉包,它們可以捕獲封閉詞法範圍中的變數值。雖然並非所有 lambdas 都能捕獲任何東西 - 像 s -> s.length() 這樣的簡單 lambda 只能捕獲並且被稱為無狀態 - 捕獲 lambdas 需要一個臨時物件來儲存捕獲的變數。在此程式碼片段中,lambda () -> j 是一個捕獲 lambda,並且可能導致在評估物件時分配物件:

public static void main(String[] args) throws Exception {
    for (int i = 0; i < 1000000000; i++) {
        int j = i;
        doSomethingWithLambda(() -> j);
    }
}

儘管由於 new 關鍵字沒有出現在程式碼段中的任何位置,因此可能不會立即明顯,但此程式碼可能會建立 1,000,000,000 個單獨的物件來表示 () -> j lambda 表示式的例項。但是,還應該注意的是,Java 1 的 未來版本可能能夠對其進行優化,以便在執行時重用 lambda 例項,或以其他方式表示。

1 - 例如,Java 9 為 Java 構建序列引入了一個可選的連結階段,這將提供進行這樣的全域性優化的機會。