문제

이것은 Java에서 허용됩니까 :

for(int i=0;i<5;i++){
  final int myFinalVariable = i;
}

내 질문의 키워드는입니다 final. 루프를 실행할 때마다 변경되는 최종 변수를 수행 할 수 있습니까? Final은 변수의 값을 변경할 수 없다고 말하면서 이것을 궁금해했습니다 (호출 만 myFinalVariable = i), 그러나 전체 변수를 다시 정의하고 있습니다 final int.

그것들은 이미 쓰레기 수집가로가는 길을 향한 루프의 이전 실행에서 변수를 가진 동일한 이름으로 완전히 다른 두 가지 변수입니까?

도움이 되었습니까?

해결책

예, 허용됩니다. 그만큼 final 키워드는 변수의 값을 변경할 수 없음을 의미합니다. 그 범위 내에서. 루프 예제의 경우 루프 하단의 범위를 벗어난 변수를 생각한 다음 루프 상단에 새로운 값으로 스코프로 돌아올 수 있습니다. 루프 내에서 변수에 할당하면 작동하지 않습니다.

다른 팁

루프의 각 반복마다 새 변수를 생성하고 있습니다. 변수는 같은 이름을 공유하지만 같은 범위가 아니기 때문에 괜찮습니다. 다음 예 ~ 아니다 일하다:

final int myFinalVariable = 0;
for(int i=0;i<5;i++){
  myFinalVariable = i;
}

변수는 스택의 위치 일뿐입니다. 변수를 가능한 한 작은 범위로 유지하고 최종적으로 변수를 유지하십시오. 그러나 범위와 최종은 단지 소스 코드입니다 ... 코드 생성/VM 관점에서 전혀 중요하지 않습니다.

특정 예에서 "int"를 사용하여 쓰레기가 만들어지지 않습니다. 그러나 두 경우 모두 물체가 생성 된 경우 쓰레기의 양과 쓰레기가 정리 할 수있는시기는 동일합니다.

다음 코드를 선택하십시오.

public class X
{
    public static void main(final String[] argv)
    {
        foo();
        bar();
    }

    private static void foo()
    {
        for(int i=0;i<5;i++)
        {
            final int myFinalVariable = i;
        }
    }

    private static void bar()
    {
        for(int i=0;i<5;i++)
        {
            int myFinalVariable = i;
        }
    }
}

컴파일러는 각 방법에 대해 동일한 바이트 코드를 생성합니다.

public class X extends java.lang.Object{
public X();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   invokestatic    #2; //Method foo:()V
   3:   invokestatic    #3; //Method bar:()V
   6:   return

private static void foo();
  Code:
   0:   iconst_0
   1:   istore_0
   2:   iload_0
   3:   iconst_5
   4:   if_icmpge       15
   7:   iload_0
   8:   istore_1
   9:   iinc    0, 1
   12:  goto    2
   15:  return

private static void bar();
  Code:
   0:   iconst_0
   1:   istore_0
   2:   iload_0
   3:   iconst_5
   4:   if_icmpge       15
   7:   iload_0
   8:   istore_1
   9:   iinc    0, 1
   12:  goto    2
   15:  return

}

루프 외부의 변수를 선언하는 다른 방법을 추가하면 변수가 선언 된 순서로 인해 약간 다른 바이트 코드가 제공됩니다). 이 버전은 변수를 최종적으로 만들 수 없습니다. 이 마지막 버전은 최선의 방법이 아닙니다 (루프 내부의 최종 변수가 가장 좋습니다).

private static void car()
{
    int myFinalVariable;

    for(int i=0;i<5;i++)
    {
        myFinalVariable = i;
    }
}

private static void car();
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_5
   4:   if_icmpge       15
   7:   iload_1
   8:   istore_0
   9:   iinc    1, 1
   12:  goto    2
   15:  return

}

대답대로, 그렇습니다. 실제로 루프의 변수를 '최종'으로 표시 할 수 있습니다. 다음은 그렇게하는 효과입니다 (Java 7, Eclipse Indigo, Mac OS X Lion).

for ( int i = 0; i < 5; i++ ) {

  // With 'final' you cannot assign a new value.
  final int myFinalVariable = i;  // Gets 0, 1, 2, 3, or 4 on each iteration.
  myFinalVariable = 7; // Compiler error: The final local variable myFinalVariable cannot be assigned.

  // Without 'final' you can assign a new value.
  int myNotFinalVariable = i;  // Gets 0, 1, 2, 3, or 4 on each iteration.
  myNotFinalVariable = 7; // Compiler is OK with re-assignment of variable's value.

}

루프 내부에 선언 된 변수는 루프의 단일 실행까지 범위가 있습니다.

루프 내부의 최종으로 변수를 선언하면 측면의 변수에 대한 차이가 없지만 최종 수정 자로 루프 외부의 변수를 선언하면 기본 유형에 할당 된 값 또는 참조 변수에 할당 된 값을 변경할 수 없습니다.

아래 예제에서는 처음 두 루프에 문제가 없습니다. 두 루프는 동일한 출력을 제공하지만 세 번째 루프는 컴파일 타임 오류를 제공합니다.

공개 수업 테스트 {

public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {
        final int j= i;
        System.out.println(j);
    }
    for (int i = 0; i < 5; i++) {
        int j= i;
        System.out.println(j);
    }

    final int j;
    for (int i = 0; i < 5; i++) {
        j= i;
        System.out.println(j);
    }
}

}

내가 틀렸다면 저를 바로 잡으십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top