2013-07-26 2 views
5

에 따라 처리하는. 그러나 컴파일 할 때 :javac의는 최종 정적 다르게 할당 방법

static boolean isBar = false; 
public static final boolean BAR = isBar; 
public static final void fooTest() { 
    if (BAR) { 
     System.out.println("gg"); 
    } 
} 

if 문은 컴파일 된 클래스 파일에 포함됩니다. 이것은 java에 static final이라는 두 가지 "유형"이 있다는 것을 의미합니까, 아니면 그냥 컴파일러 최적화입니까?

+5

컴파일러는 컴파일 타임에 '정적 최종'및 리터럴 상수로만 구성된 표현식을 평가할 수 있으며 필요에 따라 최적화를 수행 할 수 있습니다. 첫 번째 표현식은 컴파일 타임에 평가할 수 있습니다. 두 번째 것은 불가능합니다. 왜냐하면 비 최종 표현에 의존하기 때문입니다. – dasblinkenlight

+2

이것은 JIT 바이트 코드 컴파일이 물론 남겨 둘 것을 의미하지는 않습니다. –

답변

7

첫 번째 경우 컴파일러는 최적화를 수행합니다. Foo은 항상 false이 될 것이고 결코 도달하지 못할 코드를 죽일 것입니다.

두 번째 경우는 최종 변수가 아닌 변수 isBar의 값을 BAR에 할당합니다. 컴파일러는 변수 isBar이 다른 곳에서 수정되었는지 여부를 알 수 없습니다. 특히 개인이 아닌 경우에는 특히 그렇습니다. 따라서 BAR 값을 알 수 없습니다. 따라서 그는 최적화를 할 수 없습니다.

+1

실제로 컴파일러 최적화와 같은 것은 아닙니다. Java 언어 스펙에 필요한 동작입니다. (* 컴파일시 정수 *는 마술 구문입니다.)'private'은 무의미합니다 - 다른 패키지의 다른 파일에있을 수 있습니다. 소스 코드가 없어도 가능합니다. –

2

첫 번째 경우 static final 필드는 compile 시간에 알려진 상수입니다. 따라서 컴파일러는 인라인constant을 최적화합니다.

두 번째 경우 필드는 non-finalvariable이며 변경할 수 있으므로 컴파일러에서 인라인 할 수 없습니다.

class Test{ 
    public static final boolean BOOL = true; //CONSTANT KNOWN AT COMPILE TIME 


    public void someMethod(){ 
     while(BOOL){ 
      //some code 
     } 
    } 


    //OPTIMIZED VERSION DONE BY COMPILER 
    public void someMethod(){ 
     while(true){ //There is no need for accessing BOOL if it is not going to change and compiler understands that so inlines the value of constant 


     } 
    } 

} 

일부 디 컴파일러 도구를 사용하여 컴파일 된 코드를 볼 수 있으며 클래스 파일에 작성한 최적화 된 방법을 찾을 수 있습니다.

2

직접 할당을 무시하고 리터럴의 간접 할당을 고려하는 것은 컴파일러 최적화의 경우입니다.

0

메모리 내에 기존 정적 값이 하나만있을 수 있습니다. 첫 번째 블록에서 정적 최종 변수 FOO은 컴파일러가 알고있는 거짓 값으로 설정되므로 컴파일러에서 if 문을 최적화합니다. 그러나 두 번째 선언문에서는 BAR 최종 정적 변수에 isBar 정적 변수 값이 할당되므로 컴파일러는 if 문을 최적화하지 않습니다 (isBar은 부울 값이 될 수 있으며 java가 polymorphism을 지원하고 값이 할당되므로 결정할 수 없기 때문에).) 정적 변수 두 번째 블록의 메모리 위치는 컴파일러에서 값을 결정하는 데 중요합니다. 첫 번째 블록에서와 같이 다른 변수 사이에 할당없이 false 값을 알면 최적화됩니다.