2015-06-09 63 views
1

我剛開始在Java 8中圍繞lambda表達式工作。我對effectively final有點困惑。lambda表達式和全局變量

初始化局部變量是effectively final但是全局變量呢,我可以改變全局變量的值並在lambda表達式中使用它。那麼局部變量背後的原因是什麼,應該是effectively final。我找不到任何文章或關於此的javadoc。

import java.util.ArrayList; 
import java.util.List; 

public class Main { 

    private String lastname = "Thakor"; 

    public static void main(String[] args) { 
     Main objMain = new Main(); 
     objMain.test(); 
    } 

    public void test(){ 
     List<String> listStrings = new ArrayList<String>(); 
     listStrings.add("Vicky"); 
     listStrings.add("Thakor"); 

     String middlename = "V"; 
     //Local variable middlename defined in an enclosing scope must be final or effectively final 
     /* middlename = "T";*/ 

     /** 
     * In case of global variable, why lambda expression not throwing error... 
     * Local variable middlename defined in an enclosing scope must be final or effectively final 
     */ 
     lastname = "T"; 

     listStrings.stream() 
         .forEach(firstname ->{ 
          System.out.println("Firstname: " + firstname); 
          System.out.println("Middle: " + middlename); 
          System.out.println("Lastname: " + lastname); 
          System.out.println("--------------------------------------"); 
         }); 
    } 
} 

輸出

​​
+0

(http://stackoverflow.com/questions/20938095/difference-between-final-and-effectively-final) –

+2

@JordiCastilla,沒有真正 – shmosel

+0

@JordiCastilla我知道[最終和最終有效區別]的可能重複差異,但我問全球變量。 –

回答

5

當您在拉姆達引用一個「全局」變量,你真的捕捉參考this,這是有效的決賽。

考慮下面的代碼片段(未經測試):

class Main { 

    class Box { 
     int value; 
    } 

    void foo() { 
     Box box = new Box(); 
     Runnable r =() -> box.value++; 
    } 
} 

即使你改變box.value,你通過box參考,這實際上是最後做。同樣的,你的代碼就相當於

System.out.println("Lastname: " + this.lastname); 

意味着你通過this參考,這是最終的有效訪問lastname

+0

對不起,我沒有得到你的答案。我仍然困惑。 –

+0

@VickyThakor,你堅持哪部分?你明白這個例子片段嗎? – shmosel

+0

'通過此引用訪問lastname'爲什麼當通過引用訪問時,它將變量引用爲'effective final'?是什麼使它不同於局部變量?坦率地說,我不明白它背後的邏輯。你能解釋一下,java如何從編譯器級別對待它來運行時間。 –