java - oxygen - plugin swing para eclipse
Error Eclipse? Activar un nulo con solo caso por defecto (3)
Definitivamente. Si nos fijamos en el capítulo 14.11 de la especificación del lenguaje Java, indica claramente (en "discusión"):
La prohibición de usar nulo como una etiqueta de conmutador impide que uno escriba código que nunca se puede ejecutar. Si la expresión de cambio es de un tipo de referencia, como un tipo primitivo encuadrado o una enumeración, se producirá un error en tiempo de ejecución si la expresión se evalúa como nula en tiempo de ejecución.
Estaba experimentando con enum
, y encontré que lo siguiente compila y funciona bien en Eclipse (Id. De compilación: 20090920-1017, no estoy seguro de la versión exacta del compilador):
public class SwitchingOnAnull {
enum X { ,; }
public static void main(String[] args) {
X x = null;
switch(x) {
default: System.out.println("Hello world!");
}
}
}
Cuando se compila y ejecuta con Eclipse, esto imprime "Hello world!"
y sale normalmente.
Con el compilador javac
, esto lanza una NullPointerException
como se esperaba.
Entonces, ¿hay algún error en el compilador de Eclipse Java?
Este es un error. Aquí está el comportamiento especificado para una declaración de switch
acuerdo con la especificación del lenguaje Java, 3ª edición :
JLS 14.11 La declaración del switch
SwitchStatement: switch ( Expression ) SwitchBlock
Cuando se ejecuta la instrucción
switch
, primero se evalúa laExpression
. Si laExpression
evalúa comonull
, se lanza unaNullPointerException
y toda la instrucción delswitch
completa abruptamente por ese motivo.
Al parecer, el error en Eclipse no tiene nada que ver con default
caso default
o enum
en absoluto.
public class SwitchingOnAnull {
public static void main(String[] args) {
java.math.RoundingMode x = null;
switch(x) {};
switch((Integer) null) {};
switch((Character) null) {
default: System.out.println("I''ve got sunshine!");
}
}
}
El código anterior compila y ejecuta "fino" en (al menos alguna versión de) Eclipse. Cada switch
individual lanza una NullPointerException
cuando se compila con javac
, que es exactamente como los mandatos de la especificación.
La causa
Aquí está javap -c SwitchingOnAnull
cuando se compila bajo Eclipse:
Compiled from "SwitchingOnAnull.java"
public class SwitchingOnAnull extends java.lang.Object{
public SwitchingOnAnull();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
5: ldc #22; //String I''ve got sunshine!
7: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
Parece que el compilador de Eclipse se deshace de las construcciones completas del switch
completo. Desafortunadamente, esta optimización rompe la especificación del lenguaje.
Las palabras oficiales
El error ha sido archivado y asignado para su reparación.
Olivier Thomann 2010-05-28 08:37:21 EDT
Somos demasiado agresivos en la optimización.
Por:
switch((Integer) null) {};
optimizamos toda la instrucción
switch
cuando deberíamos al menos evaluar la expresión.Le daré un vistazo.
Candidato para 3.6.1.
Ver también
Sí. Según el JLS es un error:
Si la expresión de cambio es de un tipo de referencia, como un tipo primitivo encuadrado o una enumeración, se producirá un error en tiempo de ejecución si la expresión se evalúa como nula en tiempo de ejecución.