UFO ET IT

Java 컴파일러가이 변수가 항상 초기화된다는 것을 이해하지 못하는 이유는 무엇입니까?

ufoet 2021. 1. 15. 07:41
반응형

Java 컴파일러가이 변수가 항상 초기화된다는 것을 이해하지 못하는 이유는 무엇입니까?


class Foo{
    public static void main(String args[]){
        final int x=101;

        int y;
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

Java 컴파일러는 if 문의 조건이 항상 참이므로 y는 항상 초기화됩니다. 예상대로 컴파일 오류가 없습니다.

class Bar{
    public static void main(String args[]){
        final int x;
        x=101;

        int y;      
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

그러나 x의 선언과 초기화를 두 줄로 나누면 컴파일러는 조건이 항상 참이고 y가 항상 초기화된다는 것을 얻지 못하는 것 같습니다.

final int x;
x=101;
byte b;
b=x;
System.out.println(b);

여기서도 똑같은 일이 발생하고 컴파일러는 정밀도 오류를 제공합니다.

final int x=101;
byte b;
b=x;
System.out.println(b);

다시 말하지만 컴파일러는 x가 b 범위 내에 있다는 것을 이해할 수 있습니다.


컴파일러가 명령문이 실행되는지 여부를 결정하는 방법과 관련이 있습니다. JLS # 16에 정의되어 있습니다 .

각 지역 변수 및 모든 빈 최종 필드에는 해당 값에 대한 액세스가 발생할 때 확실히 할당 된 값이 있어야합니다.

귀하의 경우 컴파일러는 y확실히 할당되었는지 확인할 수 없으며 오류가 발생합니다. 이 조건이 항상 true이고있는 조건이있는 경우 그에만 가능하다는 것을 결정해야하기 때문입니다 ifA는 상수 식 .

JLS # 15.28상수 표현식을 정의 합니다 .

컴파일 타임 상수 표현식은 갑작스럽게 완료되지 않고 다음 만 사용하여 구성된 기본 유형 또는 문자열의 값을 나타내는 표현식입니다.

  • [...]
  • 상수 변수 (§4.12.4)를 참조하는 단순 이름 (§6.5.6.1).

JLS # 4.12.4 정의 된 상수를 변수 로 :

최종적이고 컴파일 타임 상수 식으로 초기화되는 기본 유형 또는 String 유형의 변수를 상수 변수라고합니다.

귀하 final int x = 101;의 경우은 상수 변수이지만 final int x; x = 101;그렇지 않습니다.


이식성을 목표로하는 일환으로 컴파일러가 수락해야하는 것과 거부해야하는 것에 대한 매우 구체적인 규칙이 있습니다. 이러한 규칙은 변수가 사용시 확실히 할당되었는지 여부를 결정할 때 제한된 형태의 흐름 분석 만 허용하고 요구합니다.

Java 언어 사양 16 장을 참조하십시오. 명확한 할당

중요한 규칙은 16.2.7의 규칙입니다 . if 문 , "if (e) S"케이스. 확실히 할당되는 규칙은 다음과 같이 확장됩니다.

V는 이후에 할당된다 (e)는 S 경우 경우에 한해 V가 후 할당 된 SV가 후 할당 된 E 때 거짓.

y는 관련 V 입니다. if 문 앞에 할당되지 않습니다. 실제로 S , y = {y = -1;} 뒤에 할당 되지만 x> 100이 false 일 때 할당되는 것은 없습니다.

따라서 y는 if 문 뒤에 확실히 할당되지 않습니다.

보다 완전한 흐름 분석은 조건 x> 100이 항상 참이라고 결정하지만 컴파일러는 이러한 특정 규칙에 따라 프로그램을 거부하기 위해 JLS에 의해 필요합니다.

최종 변수는 괜찮습니다. 규칙은 실제로 :-

"It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment."

The declaration leaves it definitely unassigned, and even the limited flow analysis can determine that x is still definitely unassigned at the assignment.


What have you done for the variable x in the second code is called blank final variable. If a final variable is not initialized when it is declared, then it is known as a blank final variable.

Many Java developers think that value of a final variable is known in the compile time. This is NOT always true. It is said that value of a blank final variable NOT known at the compile time. Hence your second code will give you a compile error. Compiler can see that you have initialized the final variable x, but compile doesn't know it's value. So compiler can't resolve the if statement. Therefor it thinks that variable y is not initialized.

You can read more about Java final variables here.

ReferenceURL : https://stackoverflow.com/questions/13235559/why-does-the-java-compiler-not-understand-this-variable-is-always-initialized

반응형