2011-01-05 3 views
23

Josh Bloch와 William Pugh가 작성한 java puzzles vid을 시간 인덱스 0 : 25 : 00-33 : 00에서 살펴보십시오. 스피커의Java Puzzlers VI에서 버그를 발견했습니다. 누군가가 설명 할 수 있습니까?

하나는 소문자 boolean 대신 Boolean 사용하는 경우, 다음 LIVING과 같이 처리됩니다 말한다 진정한 "일정 시간을 컴파일하지", 그리고이 초기화 될 때 더 이상 문제.

글쎄,이 모든 괜찮아요 멋지지만, 정적 초기화와 생성자 사이의 원래 순서로 되돌리고 간단한 "추출 방법"작업을 수행하면 어떻게되는지보십시오. 이들 두 개의 프로그램은 서로 다른 출력을 인쇄 :

public class Elvis { 
    private static final Elvis ELVIS = new Elvis(); 

    private Elvis() {} 
    private static final boolean LIVING = true; 
    private final boolean alive = LIVING; 
    private final boolean lives() {return alive;} 

    public static void main(String[] args) { 
     System.out.println(ELVIS.lives()); // prints true 
    } 
} 

그리고 리팩토링 returnTrue() 방법

public class Elvis { 
    private static final Elvis ELVIS = new Elvis(); 

    private Elvis() {} 
    private static final boolean LIVING = returnTrue(); 

    private static boolean returnTrue() { 
     return true; 
    } 

    private final boolean alive = LIVING; 
    private final boolean lives() {return alive;} 

    public static void main(String[] args) { 
     System.out.println(ELVIS.lives()); // prints false 
    } 
} 

이유 returnTrue() 메소드는이 경우의 프로그램의 출력을 변경 추출 않는와

?

+4

버그에 대한 버그/비디오에 버그가 있다는 것을 말하고 있습니까? 나는 그것의 재발이라고 생각하고 당신 stackoverflow 얻을 수 (하지만 당신은 이미 stackoverflow에 있습니다) : | – IAdapter

+3

+1 - 답변을 알지 못했습니다. 나는 누군가에게 포워드했다. – Kylar

답변

47

관찰중인 동작의 핵심은 "상수 변수"개념입니다. 이 모순은 JLS 4.12.4에서 원시 타입의 변수 또는 최종적으로 컴파일 타임 상수 표현식으로 초기화 된 타입 String으로 정의됩니다. JLS 13.1에서는 상수 필드에 대한 참조가 컴파일 타임에 나타내는 상수 값 (즉, 인라인 됨)으로 결정된다는 내용이 있습니다. 비디오의 퍼즐은 Boolean이 기본도 아니고 String도 아닌 사실에 의존합니다. 변형은 표현식에서 메소드 (returnTrue)를 호출하면 컴파일 타임 상수 표현식이 될 수 없다는 사실에 의존합니다. 어느 쪽이든, LIVING은 일정한 변수가 아니며 프로그램은 직관력이 떨어지는 행동을 표시합니다.

Java Puzzlers ("Class Warfare")의 퍼즐 93은 관련이 있으며 훨씬 더 놀라운 것입니다.

+1

퍼즐 39 또는 93? [ "Class Warfare"] (http://my.safaribooksonline.com/book/programming/java/032133678x/advanced-puzzlers/ch10lev1sec8)는 93으로 표시됩니다. – BalusC

+10

잠시 기다려주십시오. 이게 진짜 조쉬 블로치인가요? 이 질문에 답하기 위해 계정을 만들었습니까? – ripper234

+2

그는 자신의 물건을 알고 있기 때문에 명백하게. 얼마나 정통적일까요? – BalusC

5

LIVING은 런타임 표현식에 의해 초기화되므로 더 이상 컴파일 시간 상수가 아니며 그 값은 ELVIS이 생성 될 때 false입니다.

관련 문제