En Java, me dicen que cuando se realiza una comprobación nula, se debe usar == en lugar de .equals (). ¿Cúales son las razones para esto?
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 equals
es un método, si intentas invocarlo en una null
referencia, obtendrás un NullPointerException
.
Por ejemplo:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.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
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()
en null
obtendráNullPointerException
Por lo tanto, siempre es aconsejable verificar la nulidad antes de invocar el método donde sea aplicable
if(str!=null && str.equals("hi")){
//str contains hi
}
Ver también
if ("hi".equals(str))
.
someObject.equals(null)
generará un NullPointerException
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:
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.
Desde: 1.7
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 ==.
foo.equals(null)
¿Qué pasa si foo es nulo?
Obtiene una NullPointerException.
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.
Si intenta llamar a iguales en una referencia de objeto nulo, obtendrá una excepción de puntero nulo.
Según las fuentes , no importa qué usar para la implementación del método predeterminado:
public boolean equals(Object object) {
return this == object;
}
Pero no puede estar seguro equals
en la clase personalizada.
equals
que solo puede regresar false
o causar un NullPointerException
(o algo diferente si el equals
método anulado no tiene sentido).
Si usamos el método => .equals
if(obj.equals(null))
// Which mean null.equals(null) when obj will be null.
Cuando su obj sea nulo, arrojará la excepción de punto nulo.
entonces deberíamos usar ==
if(obj == null)
comparará las referencias.
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.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
¡El fragmento de ejemplo anterior devolverá igual!
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.
false
o NullPointerException
(si equals
no se reemplaza a algo malo).
Aquí hay un ejemplo donde str != null
pero str.equals(null)
cuando se usaorg.json
JSONObject jsonObj = new JSONObject("{field :null}");
Object field = jsonObj.get("field");
System.out.println(field != null); // => true
System.out.println( field.equals(null)); //=> true
System.out.println( field.getClass()); // => org.json.JSONObject$Null
EDITAR:
aquí está la clase org.json.JSONObject $ Null :
/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
* undefined.
*/
private static final class Null {
/**
* 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.
*/
@Override
public boolean equals(Object object) {
return object == null || object == this;
}
}
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.
str != null
y str.equals(null)
regresar true
al usar org.json "?
jsonObject
contiene la clave "campo", por eso field
no es nulo, tiene una referencia que contiene el json.org.JSONObject$Null
objeto
Null
como null
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:
if(str.trim().length() <=0 ) {
// is null !
}
""
tiene una longitud 0) es algo completamente diferente a una null
referencia (es decir, sin cadena).
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
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
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
lo anterior es verificar la jerarquía de un objeto, así que simplemente use
Optional.ofNullable(object1)
si solo tiene un objeto para verificar
Espero que esto ayude !!!!
Siempre puedes hacer
if (str == null || str.equals(null))
Esto primero verificará la referencia del objeto y luego el objeto en sí mismo, siempre que la referencia no sea nula.
x.equals(null)
.
equals()
y ver. Cuando lo intentes, será obvio al instante