La respuesta corta
El punto clave es este:
==
entre dos tipos de referencia es siempre una comparación de referencia
- La mayoría de las veces, por ejemplo, con
Integer
y String
, querría usar equals
en su lugar
==
entre un tipo de referencia y un tipo primitivo numérico es siempre una comparación numérica
- El tipo de referencia estará sujeto a conversión de desembalaje.
- Unboxing
null
siempre arrojaNullPointerException
- Si bien Java tiene muchos tratamientos especiales
String
, de hecho NO es un tipo primitivo
Las declaraciones anteriores son válidas para cualquier código Java válido dado . Con este entendimiento, no hay inconsistencia alguna en el fragmento que presentó.
La respuesta larga
Aquí están las secciones relevantes de JLS:
Si los operandos de un operador de igualdad son tanto del tipo de referencia como del tipo nulo , entonces la operación es igualdad de objeto.
Esto explica lo siguiente:
Integer i = null;
String str = null;
if (i == null) {
}
if (str == null) {
}
if (str == "0") {
}
Ambos operandos son tipos de referencia, y es por eso que la ==
comparación de igualdad de referencia es.
Esto también explica lo siguiente:
System.out.println(new Integer(0) == new Integer(0));
System.out.println("X" == "x".toUpperCase());
Para ==
ser igualdad numérica, al menos uno de los operandos debe ser de tipo numérico :
Si los operandos de un operador de igualdad son ambos de tipo numérico, o uno es de tipo numérico y el otro es convertible a tipo numérico, se realiza una promoción numérica binaria en los operandos. Si el tipo promocionado de los operandos es int
o long
, se realiza una prueba de igualdad de enteros; si el tipo promocionado es float or
double`, se realiza una prueba de igualdad de punto flotante.
Tenga en cuenta que la promoción numérica binaria realiza conversión de conjunto de valores y conversión de desempaquetado.
Esto explica:
Integer i = null;
if (i == 0) {
}
Aquí hay un extracto de Effective Java 2nd Edition, Item 49: Prefiere primitivas a primitivas en caja :
En resumen, use primitivas en lugar de primitivas en caja siempre que tenga la opción. Los tipos primitivos son más simples y rápidos. Si debe usar primitivas en caja, ¡tenga cuidado! Autoboxing reduce la verbosidad, pero no el peligro, de usar primitivas en caja. Cuando su programa compara dos primitivas en caja con el ==
operador, hace una comparación de identidad, que casi con seguridad no es lo que desea. Cuando su programa hace cálculos de tipo mixto que involucran primitivas en caja y sin caja, lo hace unboxing, y cuando su programa lo hace, puede lanzar NullPointerException
. Finalmente, cuando su programa encuadra valores primitivos, puede resultar en creaciones de objetos costosas e innecesarias.
Hay lugares en los que no tiene más remedio que utilizar primitivas en caja, por ejemplo, genéricos, pero de lo contrario debería considerar seriamente si se justifica la decisión de utilizar primitivas en caja.
Referencias
Preguntas relacionadas
Preguntas relacionadas