普通に宣言した場合
拡張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 様、ご指摘ありがとうございました。