In Java mi è stato detto che quando si esegue un controllo nullo si dovrebbe usare == invece di .equals (). Quali sono le ragioni di ciò?
In Java mi è stato detto che quando si esegue un controllo nullo si dovrebbe usare == invece di .equals (). Quali sono le ragioni di ciò?
Risposte:
Sono due cose completamente diverse. ==confronta l'eventuale riferimento all'oggetto contenuto in una variabile. .equals()controlla se due oggetti sono uguali in base al loro contratto per il significato di uguaglianza. È del tutto possibile che due istanze di oggetti distinti siano "uguali" in base al loro contratto. E poi c'è il dettaglio minore che poiché equalsè un metodo, se provi a invocarlo su un nullriferimento, otterrai un file NullPointerException.
Per esempio:
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ì. Tuttavia, è sovrascritto da un gran numero di classi JDK. Ma il punto non riguarda l'implementazione, ma la semantica. (Nota a margine: JDK7 è molto obsoleto.)
se invocate .equals()su nullotterreteNullPointerException
Quindi è sempre consigliabile verificare la nullità prima di invocare il metodo dove si applica
if(str!=null && str.equals("hi")){
//str contains hi
}
Vedi anche
if ("hi".equals(str)).
someObject.equals(null)solleverà a NullPointerExceptionsenza mai entrare nel metodo equals.
Objects.equals(a, b)Non solleverà NullPointerException, ma dipende comunque dal metodo "uguale" di "a" e "b"
Oltre alla risposta accettata ( https://stackoverflow.com/a/4501084/6276704 ):
A partire da Java 1.7, se vuoi confrontare due Oggetti che potrebbero essere nulli, ti consiglio questa funzione:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Questa classe è costituita da metodi di utilità statici per operare sugli oggetti. Queste utilità includono metodi null-safe o null-tolerant per calcolare il codice hash di un oggetto, restituire una stringa per un oggetto e confrontare due oggetti.
Dal: 1.7
In Java 0 o null sono tipi semplici e non oggetti.
Il metodo equals () non è costruito per i tipi semplici. I tipi semplici possono essere abbinati a ==.
foo.equals(null)
Cosa succede se foo è nullo?
Ottieni una NullPointerException.
Secondo le fonti non importa cosa usare per l'implementazione del metodo predefinito:
public boolean equals(Object object) {
return this == object;
}
Ma non puoi essere sicuro della equalslezione personalizzata.
equalspuò solo restituire falseo causare un NullPointerException(o qualcosa di diverso se il equalsmetodo sostituito non ha senso).
Object.equals è null safe, tuttavia tieni presente che se due oggetti sono null, object.equals restituirà true, quindi assicurati di controllare che gli oggetti che stai confrontando non siano null (o contengano valori null) prima di utilizzare object.equals per confronto.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Lo snippet di esempio sopra restituirà uguale!
Poiché equal è una funzione derivata dalla classe Object, questa funzione confronta gli elementi della classe. se lo usi con null restituirà una causa falsa perché il contenuto della classe non è nullo. Inoltre == confronta il riferimento a un oggetto.
falseo NullPointerException(se equalsnon è sovrascritto da qualcosa di negativo).
ecco un esempio in cui str != nullma str.equals(null)quando si utilizzaorg.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
EDIT:
ecco la classe 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)ritorna vero. Ciò interrompe il normale comportamento di Java ed è quindi fonte di confusione. Dovrebbe funzionare solo per field.equals("null"), almeno dal mio punto di vista. Non so perché gli sviluppatori della libreria pensassero che sarebbe stato utile supportare.
str != nulle str.equals(null)ritorno truequando si utilizza org.json ."?
jsonObjectcontiene la chiave "campo", ecco perché fieldnon è nullo, ha un riferimento che contiene l' json.org.JSONObject$Null oggetto
Nullcome nulle lo userei "null"invece. Ma immagino che lo abbiano fatto per evitare di richiedere stringhe. Ma anche con quella libreria, field.equals(null)è ancora quasi sempre un problema: P.
Il tuo codice infrange la legge di Demetra. Ecco perché è meglio rifattorizzare il design stesso. Come soluzione alternativa, puoi utilizzare Opzionale
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
sopra è controllare la gerarchia di un oggetto, quindi usa semplicemente
Optional.ofNullable(object1)
se hai un solo oggetto da controllare
Spero che questo ti aiuti !!!!
Potresti sempre farlo
if (str == null || str.equals(null))
Questo controllerà prima il riferimento all'oggetto e quindi controllerà l'oggetto stesso fornendo il riferimento non è nullo.
x.equals(null) .
equals()e vedere. Quando proverai sarà subito ovvio