2011-01-05 6 views
23

Dai un'occhiata a questo java puzzles vid di Josh Bloch e William Pugh, intorno all'indice del tempo 0: 25: 00-0: 33: 00.Ho trovato un bug in Java Puzzlers VI - qualcuno può spiegarlo?

Uno degli oratori dice che se si utilizza minuscole boolean invece di Boolean, poi LIVING saranno trattati come una vera e propria "compilazione costante di tempo", e non è più importante quando viene inizializzato.

Bene, questo è tutto bene e dandy, ma, dare un'occhiata a cosa succede quando si ripristina l'ordine originale tra l'init statico e il costruttore, e quindi seguirlo con una semplice operazione "Extract Method". Questi due programmi di stampa differenti uscite:

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

E con il refactoring returnTrue() metodo

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

Perché non estrarre il metodo returnTrue() cambiare il programma di uscita in questo caso?

+4

Stai dicendo che ci sono bug in un bug/video sui bug? Penso che sia chiamato ricorrenza e puoi ottenere stackoverflow (ma sei già su stackoverflow): | – IAdapter

+3

+1 - Non conoscevo la risposta. Ho inoltrato a qualcuno che lo fa. – Kylar

risposta

47

La chiave del comportamento che si sta osservando è la nozione di "variabile costante". Questo ossimoro è definito in JLS 4.12.4 come una variabile di tipo primitivo o di tipo String che è finale e inizializzata con un'espressione costante in fase di compilazione. In JLS 13.1, si dice che i riferimenti ai campi costanti vengono risolti in fase di compilazione per i valori costanti che indicano (vale a dire, sono in linea). L'enigma nel video si basa sul fatto che un booleano non è né un primitivo né una stringa. La tua variante si basa sul fatto che invocare un metodo (returnTrue) in un'espressione impedisce che si tratti di un'espressione costante in fase di compilazione. In entrambi i casi, LIVING non è una variabile costante e il programma mostra il comportamento controintuitivo.

Puzzle 93 in Java Puzzlers ("Class Warfare") è correlato e ancora più sorprendente.

+1

Puzzle 39 o 93? ["Class Warfare"] (http://my.safaribooksonline.com/book/programming/java/032133678x/advanced-puzzlers/ch10lev1sec8) è elencato come 93. – BalusC

+10

Attendi un minuto. E 'questo il vero Josh Bloch? Hai creato un account solo per rispondere a questa domanda? – ripper234

+2

Apparentemente, dal momento che conosce le sue cose. Quanto più autorevole può essere la tua risposta :) – BalusC

5

Nel secondo caso LIVING viene inizializzato dall'espressione runtime, quindi non è una costante di tempo di compilazione più, e il suo valore è false al momento ELVIS è costruito.

Problemi correlati