developer tip

"final int i"는 Java for 루프 내에서 어떻게 작동합니까?

copycodes 2020. 12. 5. 10:00
반응형

"final int i"는 Java for 루프 내에서 어떻게 작동합니까?


다음 Java 코드 조각이 컴파일되고 실행되는 것을보고 놀랐습니다.

for(final int i : listOfNumbers) {
     System.out.println(i);
}

여기서 listOfNumbers는 정수 배열입니다.

나는 최종 선언이 한 번만 할당되었다고 생각했습니다. 컴파일러가 Integer 개체를 만들고 참조하는 내용을 변경합니까?


속기가 다음과 비슷하다고 상상해보십시오.

for (Iterator<Integer> iter = listOfNumbers.iterator(); iter.hasNext(); )
{
    final int i = iter.next();
    {
        System.out.println(i);
    }
}

관련된 범위 지정 규칙에 대한 설명은 @TravisG를 참조하십시오. 이와 같은 최종 루프 변수를 사용하는 유일한 이유는 익명 내부 클래스에서이를 닫아야하는 경우입니다.

import java.util.Arrays;
import java.util.List;

public class FinalLoop {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(new Integer[] { 0,1,2,3,4 });
        Runnable[] runs = new Runnable[list.size()];

        for (final int i : list) {
            runs[i] = new Runnable() {
                    public void run() {
                        System.out.printf("Printing number %d\n", i);
                    }
                };
        }

        for (Runnable run : runs) {
            run.run();
        }
    }
}

루프 변수는 실행될 때 Runnable의 범위에 있지 않고 인스턴스화 될 때만 있습니다. final키워드가 없으면 루프 변수가 결국 실행될 때 Runnable에 표시되지 않습니다. 그렇더라도 모든 Runnables에 대해 동일한 값이 될 것입니다.

Btw, 약 10 년 전에 지역 변수에 final을 사용하는 데있어 매우 작은 속도 향상을 보셨을 것입니다. 오랫동안 그렇지 않았습니다. 이제 final을 사용하는 유일한 이유는 이와 같은 어휘 클로저를 사용하도록 허용하는 것입니다.

@mafutrct에 대한 답변 :

코드를 작성할 때 두 명의 청중을 대상으로합니다. 첫 번째는 구문 상 올바른 한, 어떤 선택을하든 만족할 수있는 컴퓨터입니다. 두 번째는 미래의 독자 (종종 자신)를위한 것이며, 여기서 목표는 코드의 '기능'을 가리지 않고 코드의 '의도'를 전달하는 것입니다. 언어 기능은 모호함을 줄이기 위해 가능한 한 적은 수의 해석과 함께 관용적으로 사용해야합니다.

루프 변수의 경우 final을 사용하여 다음 두 가지 중 하나를 전달할 수 있습니다. 단일 할당; 또는 폐쇄. 루프를 간단히 스캔하면 루프 변수가 재 할당되었는지 알 수 있습니다. 그러나 클로저를 생성 할 때 두 개의 실행 경로를 인터리빙하기 때문에 클로저가 변수를 캡처하려는 의도를 놓치기 쉽습니다. 물론, 캡처 의도를 나타 내기 위해 final 만 사용하지 않는 한, 어떤 시점에서 무슨 일이 일어나고 있는지 독자에게 분명해집니다.

참고 URL : https://stackoverflow.com/questions/3911167/how-does-final-int-i-work-inside-of-a-java-for-loop

반응형