2011-12-15 14 views
9

¿Por qué la siguiente línea de código produce un NullPointerException?NullPointerException en expresión ternaria con nulo Long

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

entiendo que unboxing se está realizando en null, pero ¿por qué?

Tenga en cuenta que

Long v = (Long) null; 

no produce la excepción.

+0

Hace una v = ((1 == 2)? Long.MAX_VALOR: (Largo) nulo); esto siempre es falso, por lo que siempre intentas lanzar nulo a Long. Esto parece no ser permitido y arroja su excepción. – evildead

+0

¿Por qué tendrías esa línea de código? ¿Curiosidad intelectual o es un fragmento del código de producción real? – Paul

+1

@Paul and evildead, parece un código de ejemplo para demostrar el orden de unboxing. – Steven

Respuesta

9

Por lo tanto, parece obvio que solo tiene que boxear si la condición es verdadera, y no debería haber boxeo si la condición es falsa. Sin embargo, la expresión de operador ternario debe tener un tipo estático. Entonces tenemos Long y long. El JLS establece que el resultado será el primitivo (igual de bien, imagínese si el operador fue, por ejemplo, + o incluso ==). Entonces el operador ternario forzará el desempaquetado, y solo entonces la asignación causará un boxeo.

Si se va a reemplazar el código con el equivalente if-else, entonces usted acaba de tener asignaciones de long a Long y desde Long a Long, que no tendría ningún unboxing y así correr bien.

IIRC, esto está cubierto es Bloch & Puzzles de Java de Gafter.

0

Desde el JSL

  1. Si el segundo y tercer operandos tienen el mismo tipo (que puede ser del tipo null), a continuación, que es el tipo de la expresión condicional.
  2. Si uno de los segundo y tercer operandos es de tipo boolean y el tipo de la otra es de tipo Boolean, entonces el tipo de la expresión condicional es boolean.

En siguiente declaración del tipo de segundo operando es long y la tercera es Long.

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

Esto funcionará si la expresión es verdadera.

Long v= 1 == 1 ? Long.MAX_VALUE : (Long) null; 

O puede lanzarlo.

Long v= 1 == 2 ? Long.valueOf(Long.MAX_VALUE) : (Long) null; 
+0

Sí, sé que está haciendo unboxing, y que no puede anular el nulo. Estaba preguntando por qué está tratando de realizar unboxing en este caso. – jonderry

+0

Eso no es del todo correcto. Está intentando deshacer la caja de un objeto 'Largo' nulo; el reparto no es el problema. Puede convertir 'null' a cualquier tipo de objeto, consulte la Especificación del lenguaje Java [sección 5.5] (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5), debajo de "Si un lanzamiento a un tipo de referencia no es un error en tiempo de compilación, hay varios casos:" – Paul

Cuestiones relacionadas