CUBは子供の白熊

Java SE 8 実践プログラミングの練習問題を解く

第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ループと同じ