以下のために、それぞれ使用しているとき、なぜループ変数は、効果的に、最終的なのですか?

huangjs:
  • ケース1:ループ毎に使用する場合には働くことができます。
    private void m10(String[] arr) {
        for (String s : arr) {
            Supplier<String> supplier = () -> {
                System.out.println(s);
                return null;
            };
            supplier.get();
        }
    }

若しくは

    private void m10(Object[] arr) {
        for (Object s : arr) {
            Supplier<String> supplier = () -> {
                System.out.println(s);
                return null;
            };
            supplier.get();
        }
    }
  • ケース2:それはコンパイル時エラーをキャッチします
    private void m11(String[] arr) {
        for (int i = 0; i < arr.length; i++) {
            Supplier<String> supplier = () -> {
                System.out.println(arr[i]);
                return null;
            };
            supplier.get();
        }
    }

ケース2において、Iは、変数が知っているi、その値は、ループ反復の間に変更されたため、効果的に、最終ではありません。ラムダは、ケース1で作業することができますしかし、なぜ私が理解することはできません。

Zabuza:

s(変更されることはありませんs = ...)。だから、コンパイラが言う「ええ、私たちは理論的としてこれをマークすることができfinalそれは何を意味するかで効果的に最終的つまり、あなたはそれをマークしませんでしたfinalが、あなたは、それはまだコンパイルしまう可能性があります。

場合あなたは、拡張forループに疑問を抱いています。

for (String s : arr)

変数は、の範囲ではないライブ外側を行いfor、再割り当てられて取得していません。すなわち、それはありません

String s = null;
for (int i = 0; i < arr.length; i++) {
    s = arr[i];
    ...
}

変数がループ内に作成されるので、その範囲は、ループに限定されます。これは、再利用が、捨てられ、各イテレーションを再作成されません。

for (int i = 0; i < arr.length; i++) {
    String s = arr[i];
    ...
}

二つの例をよく見てください。最初に、あなたが書くことができませんでしたfinal String s = null;私たちはループの中にそれを再割り当てされているので、s = arr[i];しかし、私達ができる第二の例では変数があるためs一つだけの繰り返しで知られているし、再び捨てています。だから、final String s = arr[i];大丈夫です。

あなたが使用できない理由注意点として、これについても説明sループの後。それは、その範囲がループに限定され、未知の、すでに破壊されています。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=326874&siteId=1