W Javie powiedziano mi, że podczas sprawdzania wartości null należy używać == zamiast .equals (). Jakie są tego przyczyny?
W Javie powiedziano mi, że podczas sprawdzania wartości null należy używać == zamiast .equals (). Jakie są tego przyczyny?
Odpowiedzi:
To dwie zupełnie różne rzeczy. ==
porównuje odniesienie do obiektu, jeśli istnieje, zawarte w zmiennej. .equals()
sprawdza, czy dwa obiekty są równe zgodnie z ich umową, co oznacza równość. Jest całkowicie możliwe, aby dwie różne instancje obiektów były „równe” zgodnie z ich umową. A potem jest drobny szczegół, ponieważ equals
jest to metoda, jeśli spróbujesz wywołać ją w null
odwołaniu, otrzymasz plik NullPointerException
.
Na przykład:
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
, tak. Jest jednak zastępowany przez dużą liczbę klas JDK. Ale nie chodzi o implementację, chodzi o semantykę. (Nota boczna: JDK7 jest bardzo nieaktualny.)
jeśli powołać .equals()
na null
dostanieszNullPointerException
Dlatego zawsze zaleca się sprawdzenie nieważności przed wywołaniem metody, gdziekolwiek ma to zastosowanie
if(str!=null && str.equals("hi")){
//str contains hi
}
Zobacz także
if ("hi".equals(str))
.
someObject.equals(null)
wywoła a NullPointerException
bez wprowadzania metody equals.
Objects.equals(a, b)
It nie zgłosi wyjątku NullPointerException, ale nadal zależy to od metody "równej" metody "a" i "b"
Oprócz zaakceptowanej odpowiedzi ( https://stackoverflow.com/a/4501084/6276704 ):
Od Java 1.7, jeśli chcesz porównać dwa obiekty, które mogą być zerowe, polecam tę funkcję:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Ta klasa składa się ze statycznych metod narzędziowych do wykonywania operacji na obiektach. Te narzędzia obejmują metody null-safe lub null-tolerant do obliczania kodu skrótu obiektu, zwracania ciągu dla obiektu i porównywania dwóch obiektów.
Od: 1.7
W Javie 0 lub null to typy proste, a nie obiekty.
Metoda equals () nie jest tworzona dla typów prostych. Proste typy można dopasować za pomocą ==.
foo.equals(null)
Co się stanie, jeśli foo jest zerowe?
Otrzymasz NullPointerException.
Według źródeł nie ma znaczenia, czego użyć do domyślnej implementacji metody:
public boolean equals(Object object) {
return this == object;
}
Ale nie możesz być tego pewien equals
w klasie niestandardowej.
equals
może tylko zwrócić false
lub spowodować a NullPointerException
(lub coś innego, jeśli zastąpiona equals
metoda jest nonsensowna).
Object.equals jest null bezpieczny, należy jednak pamiętać, że jeśli dwa obiekty są puste, object.equals zwróci wartość true, więc przed użyciem object.equals dla porównanie.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Przykładowy fragment powyżej zwróci wartość równą!
Ponieważ equal to funkcja wywodząca się z klasy Object, funkcja ta porównuje elementy tej klasy. jeśli użyjesz go z null, zwróci false, ponieważ zawartość klasy nie jest pusta. Dodatkowo == porównuje odniesienie do obiektu.
false
lub NullPointerException
(jeśli equals
nie zostanie zastąpiony czymś złym).
tutaj jest przykład gdzie, str != null
ale str.equals(null)
podczas używaniaorg.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
EDYCJA:
oto klasa 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)
zwraca prawdę. To łamie zwykłe zachowanie Javy i dlatego jest mylące. To powinno działać field.equals("null")
, przynajmniej z mojego punktu widzenia. Nie wiem, dlaczego programiści biblioteki pomyśleli, że warto byłoby to wspierać.
str != null
i str.equals(null)
powrócić true
podczas korzystania z org.json .”?
jsonObject
zawiera klucz "field", dlatego field
nie jest pusty, ma odniesienie, które zawiera json.org.JSONObject$Null
obiekt
Null
jak null
i "null"
zamiast tego używałbym . Ale myślę, że zrobili to, aby uniknąć wymagania Stringsa. Ale nawet z tego lib, field.equals(null)
to nadal niemal zawsze problem: P.
Twój kod łamie prawo Demeter. Dlatego lepiej zreformować sam projekt. Aby obejść ten problem, możesz użyć opcjonalnego
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
powyżej służy do sprawdzenia hierarchii obiektu, więc po prostu użyj
Optional.ofNullable(object1)
jeśli masz tylko jeden obiekt do sprawdzenia
Mam nadzieję że to pomoże !!!!
Zawsze możesz to zrobić
if (str == null || str.equals(null))
Spowoduje to najpierw sprawdzenie odwołania do obiektu, a następnie sprawdzenie samego obiektu, podając, że odwołanie nie jest null.
x.equals(null)
.
equals()
i zobaczyć. Kiedy spróbujesz, będzie to oczywiste