una - Valores nulos de cadenas y enteros en Java
comparar elementos de una matriz en java (6)
Cabe señalar que la respuesta a esta pregunta debería haber sido obvia a partir del resultado:
C:/Temp>java Test
nullnull
nullnull
nullnull
NullPointerException
public class Test {
public static void main(String[] args) {
String s = null;
String s1 = null;
Integer i = null;
Integer i1 = null;
System.out.println(s+i);
System.out.println(i+s);
System.out.println(s+s1);
try {
System.out.println(i+i1);
} catch (NullPointerException np) {
System.out.print("NullPointerException");
}
}
}
La pregunta es simple: ¿por qué recibo una NullPointerException
solo en la última línea?
Echa un vistazo al código de bytes para tu programa. Notará que su objeto nulo se pasa como un parámetro al método PrintStream.print (). El código fuente del método print () utiliza String.valueOf () como se muestra a continuación:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
La concatenación (operador +
) de cualquier cosa con un String
da como resultado un String
. Cada operando se convierte primero en una Cadena (ya sea usando toString()
o usando el valor "null"
), luego se concatena.
Pero la última operación involucra solo a Integer
, por lo que las reglas anteriores no se aplican. En lugar de una concatenación, hace una adición. Pero para agregar dos Integer
, convierte los objetos ( Integer
) a valores primitivos (int), lo cual no es posible si el número Integer
es nulo. Es por eso que obtienes una NullPointerException
.
Parece ser un caso de auto-unboxing. Si tienes dos Integer
first
y second
, entonces el resultado de su adición será first.intValue() + second.intValue()
. Dado que ambos son nulos, eso resulta en una NPE.
Su código hace uso de dos operadores aditivos diferentes. Las tres primeras líneas usan concatenación de cadenas , mientras que la última usa suma numérica .
La concatenación de cadenas está bien definida para convertirse en null
en "null"
:
- Si la referencia es
null
, se convierte a la cadena"null"
(cuatro caracteres ASCIIn
,u
,l
,l
).
Por lo tanto, no hay NPE.
Agregar dos objetos Integer
juntos requiere que se unboxed . Esto hace que la referencia null
sea eliminada, lo que lleva a la NPE:
- Si
r
es nulo, la conversión unboxing lanza unaNullPointerException
Tenga en cuenta que los tres primeros usos del operador implican concatenación de cadenas. Sólo el último es la suma numérica real. Cuando se trata de concatenación de cadenas (donde está implicada s
variable s
), el compilador de Java utiliza algún truco inteligente para mejorar el rendimiento. Reemplaza al operador +
con StringBuilder
. Por ejemplo, su primera línea se traduce a:
StringBuilder tmp = new StringBuilder();
tmp.append(s);
tmp.append(i);
System.out.println(tmp);
StringBuilder
es null
amigable, por lo que no importa lo que pase como argumento, lo reemplaza muy bien con una cadena "null"
.
La situación es diferente en la última línea. Allí hace referencia a dos objetos Integer
. Lo único que JVM puede hacer aquí es desempaquetarlos ( i.intValue()
) y realizar el cálculo real. Unboxing de null
provoca NullPointerException
.