2011-01-05 5 views
23

Eche un vistazo a este java puzzles vid de Josh Bloch y William Pugh, en el índice de tiempo 0: 25: 00-0: 33: 00.Encontré un error en Java Puzzlers VI. ¿Alguien puede explicarlo?

Uno de los altavoces dice que si se utiliza minúsculas boolean en lugar de Boolean, entonces LIVING será tratado como un verdadero "tiempo de compilación constante", y ya no importa cuando se inicializa.

Bueno, todo esto está muy bien, pero echa un vistazo a lo que sucede cuando vuelves al orden original entre el init estático y el constructor, y luego lo sigues por una simple operación "Extraer método". Estos dos programas se imprimen diferentes salidas:

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

Y con la refactorizado returnTrue() método

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

¿Por qué el método de extracción returnTrue() cambia la salida del programa en este caso?

+4

¿Estás diciendo que hay errores en un error/video sobre errores? creo que se llama recurrencia y puedes obtener stackoverflow (pero ya estás en stackoverflow): | – IAdapter

+3

+1 - No sabía la respuesta. Me reenvió a alguien que lo hace. – Kylar

Respuesta

47

La clave del comportamiento que está observando es la noción de "variable constante". Este oxímoron se define en JLS 4.12.4 como una variable de tipo primitivo o tipo String que es final e inicializado con una expresión constante en tiempo de compilación. En JLS 13.1, indica que las referencias a los campos constantes se resuelven en tiempo de compilación a los valores constantes que denotan (es decir, están en línea). El enigma en el video se basa en el hecho de que un booleano no es ni una primitiva ni una cadena. Su variante se basa en el hecho de que invocar un método (returnTrue) en una expresión evita que sea una expresión constante en tiempo de compilación. De cualquier forma, LIVING no es una variable constante y el programa muestra el comportamiento contrario a la intuición.

Puzzle 93 en Java Puzzlers ("Class Warfare") está relacionado, y aún más sorprendente.

+1

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

+10

Espere un minuto. ¿Es este el verdadero Josh Bloch? ¿Creó una cuenta solo para responder esta pregunta? – ripper234

+2

Aparentemente, ya que él sabe sus cosas. Cuán más autoritativa puede ser tu respuesta :) – BalusC

5

En el segundo caso LIVING se inicializa por la expresión de tiempo de ejecución, por lo tanto no es una constante de tiempo de compilación más, y su valor es false en el momento en ELVIS se construye.

Cuestiones relacionadas