普通に宣言した場合
拡張for文、forEach文を普通に宣言すると以下のようになります。
final宣言していないため、再代入可能です(普通のfor文は原理的に再代入が必須なので飛ばします)。
List<Integer> intList = Arrays.asList(1, 2, 3, 4);
for(int i : intList) {
i = 0; // 書き換えられる
}
intList.forEach(it -> {
it = 0; // 書き換えられる
});
この記事では、これらの内容を再代入不能な形に書き換えます。
変数をimmutableにする
拡張for文の場合
finalで宣言することでimmutableにできます。
for(final int i : intList) {
i = 0; // final宣言しているため再代入不可でコンパイルエラー
}
forEach文の場合
以下のように、カッコで括って型を指定することで引数をfinalにできます。
intList.forEach((final int it) ->
it = 0; // final宣言しているため再代入不可でコンパイルエラー
);
別解
一応ですが、無名クラスとして実装する場合も引数をfinalにできます。
Consumer<Integer> finalConsumer = new Consumer<Integer>() {
@Override
public void accept(final Integer it) {
it = 0; // final宣言しているため再代入不可でコンパイルエラー
}
};
お詫び
この記事は当初公開した際「インデックスをimmutableにできるのはfor文、拡張for文、forEach文の内拡張for文だけ」というタイトル・内容でしたが、@saka1029 様のご指摘の通り、これは誤りでしたので、タイトル・内容共に全面的に書き直しを行いました。
@saka1029 様、ご指摘ありがとうございました。