java 8新特性學習之五:Java 8 lambda表示式初步第五回

孫小光發表於2016-06-17

一、lambda表示式和變數捕獲
在lambda表示式中,可以訪問其外層作用域內定義的變數。lambda表示式可以使用其外層類定義的例項或靜態變數。lambda表示式也可以顯式或隱式地訪問this變數,該變數引用lambda表示式的外層類的呼叫例項。lambda表示式可以獲取或設定其外層類的例項或靜態變數的值,以及呼叫其外層類定義的方法。
但是,當lambda表示式使用其外層作用域內定義的區域性變數時,會產生一種特殊的情況,稱為變數捕獲。在這種情況下,lambda表示式只能使用實質上final的區域性變數。實質上final的變數是指在第一次賦值以後,值不再發生變化的變數。沒有必要顯式地將這種變數宣告為final,不過那樣做也不是錯誤(外層作用域的this引數自動是實質上final的變數,lambda表示式沒有自己的this引數)。
lambda表示式不能修改外層作用域內的區域性變數,理解這一點很重要。修改區域性變數會移除其實質上的final狀態,從而使捕獲該變數不合法。

interface MyFunc{
    int func(int n);
}
class VarCapture{
    public static void main(String args[]){
        int num = 10;
        MyFunc mylambda=(n)->{
            int v = num+n;
            return v;
        };
   }
}  

以上num實質上是final變數,所以可以在mylambda內使用。但是,如果修改了num,不管是在lambda表示式內還是表示式外,num就會丟失其實質上final的狀態。這會導致發生錯誤,程式將無法通過編譯。 需要重點強調,lambda表示式可以使用和修改其呼叫類的例項變數,只是不能使用其外層作用域內的區域性變數,除非該變數實質上是final變數。

相關文章