todas - Encontré un error en Java Puzzlers VI. ¿Alguien puede explicarlo?




todas las excepciones en java (2)

Echa un vistazo a este vid de java puzzles de Josh Bloch y William Pugh, alrededor del índice de tiempo 0: 25: 00-0: 33: 00.

Uno de los oradores dice que si usa un valor boolean en minúscula en lugar de un valor Boolean , LIVING se tratará como una verdadera "constante de tiempo de compilación", y ya no importa cuando se inicializa.

Bueno, todo esto está muy bien, pero mire lo que sucede cuando vuelve al orden original entre el inicio estático y el constructor, y luego realice un seguimiento mediante una simple operación de "Método de extracción". Estos dos programas 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 el returnTrue() refactored 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
    }
}

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

https://code.i-harness.com


En el segundo caso, LIVING se inicializa con la expresión runtime, por lo que ya no es una constante de compilación y su valor es false en el momento en que se construye ELVIS .


La clave del comportamiento que está observando es la noción de "variable constante". Este oxymoron se define en JLS 4.12.4 como una variable de tipo primitivo o tipo String que es final e inicializa con una expresión constante de tiempo de compilación. En JLS 13.1 , dice que las referencias a campos constantes se resuelven en tiempo de compilación a los valores constantes que denotan (es decir, están en línea). El rompecabezas en el video se basa en el hecho de que un booleano no es ni un primitivo ni un String. 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 manera, VIVIR no es una variable constante y el programa muestra el comportamiento contraintuitivo.

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





java