Lo más fácil es intentar verificar nulo con equals()y ver. Cuando lo intentes, será obvio al instante
Goran Jovic
Por cierto, una búsqueda en Google con palabras clave "java null check" (sin comillas) me dio como uno de los principales éxitos de este hilo , que tiene la misma información que las respuestas aquí.
Mitch Schwartz
Respuestas:
179
Son dos cosas completamente diferentes. ==compara la referencia del objeto, si la hay, contenida por una variable. .equals()comprueba si dos objetos son iguales según su contrato para lo que significa igualdad. Es completamente posible que dos instancias distintas de objetos sean "iguales" de acuerdo con su contrato. Y luego está el pequeño detalle de que, dado que equalses un método, si intentas invocarlo en una nullreferencia, obtendrás un NullPointerException.
Por ejemplo:
classFoo{privateint data;Foo(int d){this.data = d;}@Overridepublicboolean equals(Object other){if(other ==null|| other.getClass()!=this.getClass()){returnfalse;}return((Foo)other).data ==this.data;}/* In a real class, you'd override `hashCode` here as well */}Foo f1 =newFoo(5);Foo f2 =newFoo(5);System.out.println(f1 == f2);// outputs false, they're distinct object instancesSystem.out.println(f1.equals(f2));// outputs true, they're "equal" according to their definitionFoo f3 =null;System.out.println(f3 ==null);// outputs true, `f3` doesn't have any object reference assigned to itSystem.out.println(f3.equals(null));// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anythingSystem.out.println(f1.equals(f3));// Outputs false, since `f1` is a valid instance but `f3` is null,// so one of the first checks inside the `Foo#equals` method will// disallow the equality because it sees that `other` == null
@Xepoch: No, generalmente no creo campos públicos (aunque en realidad no importa para este ejemplo de ninguna manera). ¿Por qué?
TJ Crowder
@TJ Crowder "Son dos cosas completamente diferentes ..." en general sí. Sin embargo, la implementación predeterminada de ambos es la misma, si mi comprensión es correcta. Mirando el código fuente, .equals () básicamente hace una comprobación ==. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
Ayush
1
@Ayush: ese es el valor predeterminado Object, sí. Sin embargo, está anulado por un gran número de clases JDK. Pero lo importante no es la implementación, sino la semántica. (Nota al margen: JDK7 está muy desactualizado.)
TJ Crowder
Bien, eso tiene sentido, solo quería aclarar.
Ayush
38
si se invoca .equals()en nullobtendráNullPointerException
Por lo tanto, siempre es aconsejable verificar la nulidad antes de invocar el método donde sea aplicable
Su ejemplo generalmente se escribe mejor como if ("hi".equals(str)).
ColinD
3
@ user368186: el punto no es si el método igual incluye una verificación nula. Si su referencia de objeto es nula, entonces la llamada someObject.equals(null)generará un NullPointerExceptionsin ingresar el método igual.
Dave Costa
2
@ColinD De acuerdo, solo demostrando aquí
Jigar Joshi
2
Siempre es aconsejable evitar los nulos a toda costa, por lo que no necesita cheques nulos en absoluto;).
fwielstra
2
Siempre puede usar Objects.equals(a, b)No aumentará NullPointerException, pero aún depende del método "igual" de "a" y "b"
Desde Java 1.7, si desea comparar dos objetos que pueden ser nulos, le recomiendo esta función:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Esta clase consta de métodos de utilidad estática para operar en objetos. Estas utilidades incluyen métodos nulos seguros o nulos tolerantes para calcular el código hash de un objeto, devolver una cadena para un objeto y comparar dos objetos.
Si una variable Object es nula, no se puede invocar un método equals () sobre ella, por lo tanto, una comprobación de referencia de objeto de null es adecuada.
Object.equals es nulo seguro, sin embargo, tenga en cuenta que si dos objetos son nulos, object.equals devolverá verdadero, así que asegúrese de comprobar que los objetos que está comparando no son nulos (o tienen valores nulos) antes de usar object.equals para comparación.
Como lo indica el JavaDoc (siempre es aconsejable leerlos): Consequently, if both arguments are null, true is returned. ...:)
Thomas
1
Debido a que igual es una función derivada de la clase Object, esta función compara elementos de la clase. si lo usa con nulo, devolverá una causa falsa porque el contenido de la clase no es nulo. Además == compara la referencia a un objeto.
/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
* undefined.
*/privatestaticfinalclassNull{/**
* A Null object is equal to the null value and to itself.
*
* @param object
* An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or
* null.
*/@Overridepublicboolean equals(Object object){return object ==null|| object ==this;}}
El problema aquí es que field.equals(null)vuelve verdadero. Esto rompe el comportamiento habitual de Java y, por lo tanto, es confuso. Solo debería funcionar field.equals("null"), al menos en mi punto de vista. No sé por qué los desarrolladores de la biblioteca pensaron que sería bueno apoyar esto.
Tom
Por cierto, su primera oración tiene un problema de gramática y no está claro qué quiere decir con ella. ¿Quiere decir "Aquí hay un ejemplo de dónde str != nully str.equals(null)regresar trueal usar org.json "?
Tom
Creo que es porque jsonObjectcontiene la clave "campo", por eso fieldno es nulo, tiene una referencia que contiene el json.org.JSONObject$Null objeto
dina
Sí, pero no lo trataría Nullcomo nully lo usaría "null"en su lugar. Pero supongo que hicieron eso para evitar requerir cadenas. Pero incluso con ese lib, field.equals(null)sigue siendo casi siempre un problema: P.
Tom
0
Así que nunca me confundo y evito problemas con esta solución:
Además, una cadena vacía (que ""tiene una longitud 0) es algo completamente diferente a una nullreferencia (es decir, sin cadena).
Thomas
0
Me he encontrado con este caso anoche.
Yo determino eso simplemente que:
No existe el método equals () para nulo Entonces, no puede invocar un método inexistente si no tiene
- >>> Esa es la razón por la cual usamos == para verificar nulo
equals()
y ver. Cuando lo intentes, será obvio al instanteRespuestas:
Son dos cosas completamente diferentes.
==
compara la referencia del objeto, si la hay, contenida por una variable..equals()
comprueba si dos objetos son iguales según su contrato para lo que significa igualdad. Es completamente posible que dos instancias distintas de objetos sean "iguales" de acuerdo con su contrato. Y luego está el pequeño detalle de que, dado queequals
es un método, si intentas invocarlo en unanull
referencia, obtendrás unNullPointerException
.Por ejemplo:
fuente
public int data
?Object
, sí. Sin embargo, está anulado por un gran número de clases JDK. Pero lo importante no es la implementación, sino la semántica. (Nota al margen: JDK7 está muy desactualizado.)si se invoca
.equals()
ennull
obtendráNullPointerException
Por lo tanto, siempre es aconsejable verificar la nulidad antes de invocar el método donde sea aplicable
Ver también
fuente
if ("hi".equals(str))
.someObject.equals(null)
generará unNullPointerException
sin ingresar el método igual.Objects.equals(a, b)
No aumentará NullPointerException, pero aún depende del método "igual" de "a" y "b"Además de la respuesta aceptada ( https://stackoverflow.com/a/4501084/6276704 ):
Desde Java 1.7, si desea comparar dos objetos que pueden ser nulos, le recomiendo esta función:
fuente
Objects.equals(null, null)
volverátrue
, tenga eso en cuenta.En Java 0 o nulo son tipos simples y no objetos.
El método equals () no está diseñado para tipos simples. Los tipos simples se pueden combinar con ==.
fuente
¿Qué pasa si foo es nulo?
Obtiene una NullPointerException.
fuente
Si una variable Object es nula, no se puede invocar un método equals () sobre ella, por lo tanto, una comprobación de referencia de objeto de null es adecuada.
fuente
Si intenta llamar a iguales en una referencia de objeto nulo, obtendrá una excepción de puntero nulo.
fuente
Según las fuentes , no importa qué usar para la implementación del método predeterminado:
Pero no puede estar seguro
equals
en la clase personalizada.fuente
equals
que solo puede regresarfalse
o causar unNullPointerException
(o algo diferente si elequals
método anulado no tiene sentido).Si usamos el método => .equals
Cuando su obj sea nulo, arrojará la excepción de punto nulo.
entonces deberíamos usar ==
comparará las referencias.
fuente
Object.equals es nulo seguro, sin embargo, tenga en cuenta que si dos objetos son nulos, object.equals devolverá verdadero, así que asegúrese de comprobar que los objetos que está comparando no son nulos (o tienen valores nulos) antes de usar object.equals para comparación.
¡El fragmento de ejemplo anterior devolverá igual!
fuente
Consequently, if both arguments are null, true is returned. ...
:)Debido a que igual es una función derivada de la clase Object, esta función compara elementos de la clase. si lo usa con nulo, devolverá una causa falsa porque el contenido de la clase no es nulo. Además == compara la referencia a un objeto.
fuente
false
oNullPointerException
(siequals
no se reemplaza a algo malo).Aquí hay un ejemplo donde
str != null
perostr.equals(null)
cuando se usaorg.json
EDITAR: aquí está la clase org.json.JSONObject $ Null :
fuente
field.equals(null)
vuelve verdadero. Esto rompe el comportamiento habitual de Java y, por lo tanto, es confuso. Solo debería funcionarfield.equals("null")
, al menos en mi punto de vista. No sé por qué los desarrolladores de la biblioteca pensaron que sería bueno apoyar esto.str != null
ystr.equals(null)
regresartrue
al usar org.json "?jsonObject
contiene la clave "campo", por esofield
no es nulo, tiene una referencia que contiene eljson.org.JSONObject$Null
objetoNull
comonull
y lo usaría"null"
en su lugar. Pero supongo que hicieron eso para evitar requerir cadenas. Pero incluso con ese lib,field.equals(null)
sigue siendo casi siempre un problema: P.Así que nunca me confundo y evito problemas con esta solución:
fuente
""
tiene una longitud 0) es algo completamente diferente a unanull
referencia (es decir, sin cadena).Me he encontrado con este caso anoche.
Yo determino eso simplemente que:
fuente
Tu código infringe la ley de Demeter. Por eso es mejor refactorizar el diseño en sí. Como solución alternativa, puede usar Opcional
lo anterior es verificar la jerarquía de un objeto, así que simplemente use
si solo tiene un objeto para verificar
Espero que esto ayude !!!!
fuente
Siempre puedes hacer
Esto primero verificará la referencia del objeto y luego el objeto en sí mismo, siempre que la referencia no sea nula.
fuente
x.equals(null)
.