第1章 ラムダ式とは : 問題 8 : ラムダ式とクロージャ
問題 8
ラムダ式が次のような拡張for
ループ内の値をキャプチャした場合、
String[] names = { "Peter", "Paul", "Mary" }; List<Runnable> runners = new ArrayList<Runnable>(); for (String name : names) { runners.add(() -> System.out.println(name)); }
これらを実行すると、各ラムダ式は異なる値をキャプチャするか?
それとも最後の値をキャプチャするか?
解答
各ラムダ式は異なる値をキャプチャする。
つまり、Java のラムダ式はクロージャになっているということ(ブラボー)。
おそらく、このラムダ式は以下のようなクラスが定義され
class Foo implements Runnable { private String name; public Foo(String name) { this.name = name; } public void run() { System.out.println(name); } }
for
ループでは、このインスタンスが生成されたのだろう。
for (String name : names) { runners.add(new Foo(name)); }
さらに問題
通常のfor
ループで値をキャプチャした場合はどうか?
String[] names = { "Peter", "Paul", "Mary" }; List<Runnable> runners = new ArrayList<Runnable>(); for (int i = 0; i < names.length; i++) String name = names[i]; // effectively final エラー回避のため runners.add(() -> System.out.println(name)); }
解答
拡張for
ループと同じ