12

Duplicar posible:
Is 1/0 a legal Java expression?¿Por qué una constante Java dividida por cero produce un error de tiempo de compilación?

¿Por qué compilar el código?

class Compiles { 
    public final static int A = 7/0; 
    public final static int B = 10*3; 

    public static void main(String[] args) {} 
} 

Si echo un vistazo en el archivo de clase compilada, puedo ver que B se ha evaluado a 30, y que todavía es un 7/0.

Por lo que yo entiendo, la expresión JSL donde se divide por cero no es una constante.

Ref: JLS 15.28

Mi declaración anterior es debido a esta línea:

A-tiempo de compilación expresión de la constante es una expresión que denota un valor de tipo primitivo

Por lo tanto dividiendo por cero no se evalúa a un valor primitivo.

Lo que realmente no entiendo es por qué el compilador lo permite de todos modos? Para que quede claro, mi código anterior bloquea el tiempo de ejecución con un "java.lang.ExceptionInInititizerError"

Como me parece, el compilador amenaza cualquier variable estática final como una constante y lo evalúa en tiempo de compilación. Eso significa que el compilador ya ha intentado evaluar A, pero como era una división por cero, simplemente lo dejó pasar. Sin error de tiempo de compilación. Pero esto parece muy extraño ... ¡El compilador sabe que es una división por cero y que bloqueará el tiempo de ejecución, pero, no obstante, no marca un error de compilación!

¿Alguien me puede explicar por qué?

+1

¿Hay alguna instancia de división por cero produciendo errores de tiempo de compilación en absoluto? Si dividieras por cero en el código de procedimiento normal, obtendrías una 'ArithmeticException' en tiempo de ejecución, así que no veo nada sorprendente acerca de que esto también sea posible a través del compilador. – BoltClock

Respuesta

6

Lanzar el java.lang.ExceptionInInitializerError es el único comportamiento correcto.

Si su código no se compiló, se habría rechazado un programa Java perfectamente válido, y eso hubiera sido un error.

La única alternativa correcta para poner 7/0 en el código compilado, sería en realidad lanzar explícitamente un ExceptionInInitializerError, pero ¿cuánto más útil es eso?

El compilador sabe que es una división por cero y que se colgará en tiempo de ejecución, pero sin embargo lo hace bandera de un error de compilación!

En realidad, yo no estaría de acuerdo con eso ... lo haría este programa accidente?

class Compiles { 
    public final static int A = 7/0; 
    public final static int B = 10*3; 

    public static void main(String[] args) {} 

} 

public class Test { 

    // Application entry point. 
    public static void main(String[] args) { 
     try { 
      new Compiles(); 

      launchTheMissiles(); 

     } catch (ExceptionInInitializerError e) { 

      doUsefulStuff(); 

     } 
    } 
} 
+0

Su programa no se bloqueará. Pero el mío lo hará. ¿Entonces siempre pondrás la inicialización de nuevos objetos en un try/catch? – laitinen

+1

Sí. Siempre pongo try/catch alrededor de las instancias de las clases 'ExceptionInitializerError'. ;- D – aioobe

2

JLS 15.28 Constant Expression:

A-tiempo de compilación expresión de la constante es una expresión que denota un valor de tipo primitivo o una cadena que no complete abruptamente y se compone utilizando sólo el siguiente:

...

Por lo tanto es 7/0 no es una constante en tiempo de compilación, ya que su evaluación se completa abruptamente debido a la división por cero. Por lo tanto, se trata como una expresión de tiempo de ejecución normal y arroja una excepción en tiempo de ejecución.

+0

¡Eso fue lo que dije! Estoy totalmente de acuerdo. Pero me parece extraño que no lo marque como un error de compilación, ya que el compilador ya ha evaluado la expresión. – laitinen

+3

Si acepta que no es una constante * en tiempo de compilación *, no debería sorprenderse que la evaluación se posponga a * runtime * y, en consecuencia, genere una excepción. – aioobe

+3

que probablemente sea un parche para justificar el comportamiento de javac existente (no puede cambiarlo debido a la compatibilidad con versiones anteriores). la especificación podría haber dicho muy bien: "blah blah, ** y es un error de tiempo de compilación si la expresión no se computa **" – irreputable

Cuestiones relacionadas