lambda表示式:變數作用域
阿新 • • 發佈:2019-02-03
如下程式碼中的變數count和text,沒有在lambda表示式中被定義,而是repeatMessage方法的引數變數
public void repeatMessage(String text, int count){ Runnable r = () -> { for (int i=0; i<count; i++){ System.out.println(text); Thread.yield(); } }; new Thread(r).start(); }
一個lambda表示式包括三部分:
1.一段程式碼。
2.引數。
3.只有變數的值。(“自由”指的是那些不是引數並且沒有在程式碼中定義的變數)
在lambda表示式中,被引用的變數的值不可以被更改,如下程式碼:
原因:更改lambda表示式中的變數不是執行緒安全的,自增、自減操作不是原子性的。public void repeatMessage(String text, int count){ Runnable r = () -> { while (count > 0){ count --; //錯誤,不能更改 System.out.println(text); Thread.yield(); }; }; new Thread(r).start(); }
內部類也會捕獲閉合作用域中的值。在Java8前,內部類只允許訪問final的區域性變數。為了適應lambda表示式,這條規則現在放寬了。一個內部類可以訪問任何有效的final區域性變數,即任何值不會發生變化的變數。
在lambda表示式中不允許宣告一個與區域性變數同名的引數或者區域性變數,如下程式碼:
Path first = Paths.get("/usr/bin"); Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); //錯誤:變數first已經被定義了
lambda表示式中的this關鍵字的意義,如下程式碼:
class Application {
public void doWork(){
Runnable runner = () -> {
System.out.println(this.toString());
};
}
}
this.toString()會呼叫Application物件的toString方法,而不是Runnable例項的toString方法。