2012-08-10 8 views
16

Por ejemplo:¿Por qué el compilador de Java a veces permite el desempaquetado de nulo?

int anInt = null; 

falla en tiempo de compilación, pero

public static void main(String[] args) { 
    for (int i = 0; i < 10; i++) { 
    System.out.println("" + getSomeVal()); 
    } 
} 
public static int getSomeVal() { 
    return new Random().nextBoolean() ? 1 : null; 
} 

falla (por lo general) en tiempo de ejecución. Intentar devolver solo null también dará como resultado un error de compilación, así que supongo que hay algo acerca de tener varias rutas de acceso que hace que el compilador infiera que null es potencialmente un autoboxed int? ¿Por qué no puede javac compilar ambos casos con el mismo error?

Respuesta

20

En el primer caso, el compilador sabe que usted está tratando de unbox una constante en tiempo de compilación de null.

En el segundo caso, el tipo de la expresión condicional es Integer, por lo que está escrito de manera efectiva:

Integer tmp = new Random().nextBoolean() ? 1 : null; 
return (int) tmp; 

... por lo que el unboxing no está sucediendo en una expresión constante, y el compilador lo permitirá

Si la ha cambiado para forzar la expresión condicional a ser de tipo int por unboxing hay, que fracasaría:

// Compile-time failure 
return new Random().nextBoolean() ? 1 : (int) null; 
+0

El primer caso implica un "tipo" nulo que se convierte implícitamente en un tipo int, r Esulting en un error de compilación.El segundo caso implícitamente arroja nulo al tipo de variable de la izquierda, que es el tipo de expresión en lugar del valor de retorno. Supongo que una lectura cuidadosa de JLS 15.25 "Si el segundo y tercer operandos tienen el mismo tipo (que puede ser del tipo nulo), entonces ese es el tipo de expresión condicional". te da esto, ya que el compilador java no puede dar un tipo nulo a null y por lo tanto se ve forzado a usar Integer para ambos al desempaquetar el 1. Respuesta muy clara, gracias. – MilesHampson

2

boxeo oculta parcialmente la distinción entre los primitivos y los correspondientes objetos de envoltura, pero doesn no lo elimine

Hay dos distinciones que no son modificados por el boxeo:

  • objetos puede ser nulo, mientras que los primitivos no pueden
  • objetos tienen tanto el Estado como la identidad, mientras que las primitivas tienen único estado (el valor)

Ocasionalmente, estas diferencias pueden causar problemas al usar el boxeo.

Algunos puntos a recordar:

  • tener cuidado con nulos. El desempaquetado automático de un objeto nulo causará un NullPointerException.
  • comparando los artículos con == y equals se debe hacer con cuidado.
1

No se puede asignar a un int nula

int anInt = null; 

Java permite esto, ya que no está asignando nula a un int

System.out.println("" + getSomeVal()); //null was just converted to a srting and was printed 

Si se realiza esto, se puede obtener el error

int anInt = getSomeVal(); 
Cuestiones relacionadas