2011-01-05 6 views
23

Spójrz na to java puzzles vid autorstwa Josha Blocha i Williama Pugha, o indeksie czasowym 0: 25: 00-0: 33: 00.Znalazłem błąd w Java Puzzlers VI - czy ktoś może to wyjaśnić?

Jednym z prelegentów mówi, że jeśli używasz małe boolean zamiast Boolean, następnie LIVING będą traktowane jako prawdziwy „kompilacji stałą”, a to już nie ma znaczenia, gdy jest on zainicjowany.

Cóż, to wszystko jest cacy, ale spójrz na to, co się dzieje, kiedy powróci do pierwotnego celu między statyczne startowych i konstruktora, a następnie go zwykłą „Wyciąg metoda” operacji. Te dwa programy drukować różne wyjścia:

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 
    } 
} 

I z refactored returnTrue() metody

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 
    } 
} 

Dlaczego wydobycia metodą returnTrue() zmienić wyjście programu w tym przypadku?

+4

Czy mówisz, że są błędy w bug/video o błędach? Myślę, że to się nazywa nawrotem i możesz dostać stackoverflow (ale już jesteś na stackoverflow): | – IAdapter

+3

+1 - Nie znałem odpowiedzi. Przekazałem komuś, kto to robi. – Kylar

Odpowiedz

47

Kluczem do zachowania, które obserwujesz, jest pojęcie "zmiennej stałej". Ten oksymoron jest zdefiniowany w JLS 4.12.4 jako zmienna pierwotnego typu lub typu String, która jest ostateczna i zainicjowana za pomocą stałego wyrażenia w czasie kompilacji. W dokumencie JLS 13.1 podano, że odniesienia do pól stałych są rozwiązywane w czasie kompilacji do stałych wartości, które oznaczają (tj. Są one wstawione). Układanka w filmie polega na tym, że Boolean nie jest ani prymitywem, ani łańcuchem. Twój wariant opiera się na fakcie, że wywołanie metody (returnTrue) w wyrażeniu uniemożliwia jej ciągłe wyrażenie w czasie kompilacji. Tak czy inaczej, LIVING nie jest stałą zmienną i program wyświetla sprzeczne z intuicją zachowanie.

Puzzle 93 w Java Puzzlers ("Class Warfare") są powiązane, a jeszcze bardziej zaskakujące.

+1

Puzzle 39 lub 93? ["Class Warfare"] (http://my.safaribooksonline.com/book/programming/java/032133678x/advanced-puzzlers/ch10lev1sec8) znajduje się na liście 93. – BalusC

+10

Zaczekaj chwilę. Czy to prawdziwy Josh Bloch? Czy założyłeś konto, aby odpowiedzieć na to pytanie? – ripper234

+2

Wygląda na to, że zna się na rzeczy. Jak bardziej autorytatywna może być twoja odpowiedź :) – BalusC

5

W drugim przypadku LIVING jest inicjowany przez ekspresję wykonawczego, a zatem nie jest stała w czasie kompilacji więcej, a jej wartość jest false w momencie ELVIS jest zbudowana.

Powiązane problemy