Najłatwiej jest sprawdzić wartość null equals()i zobaczyć. Kiedy spróbujesz, będzie to oczywiste
Goran Jovic
Nawiasem mówiąc, wyszukiwanie google ze słowami kluczowymi „java null check” (bez cudzysłowów) dało mi jako jedno z najpopularniejszych trafień w tym wątku , który zawiera te same informacje, co odpowiedzi tutaj.
Mitch Schwartz
Odpowiedzi:
179
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ż equalsjest to metoda, jeśli spróbujesz wywołać ją w nullodwołaniu, otrzymasz plik NullPointerException.
Na przykład:
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: Nie, generalnie nie tworzę pól publicznych (chociaż tak naprawdę nie ma to znaczenia w tym przykładzie). Czemu?
TJ Crowder
@TJ Crowder "To dwie zupełnie różne rzeczy ..." ogólnie tak. Jednak domyślna implementacja obu jest taka sama, jeśli moje rozumienie jest poprawne. Patrząc na kod źródłowy, .equals () w zasadzie sprawdza ==. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
Ayush
1
@Ayush - to jest domyślne ustawienie 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.)
TJ Crowder
Racja, to ma sens, chciałem tylko wyjaśnić.
Ayush
38
jeśli powołać .equals()na nulldostanieszNullPointerException
Dlatego zawsze zaleca się sprawdzenie nieważności przed wywołaniem metody, gdziekolwiek ma to zastosowanie
Twój przykład jest ogólnie lepiej napisany jako if ("hi".equals(str)).
ColinD
3
@ user368186: nie chodzi o to, czy metoda equals obejmuje sprawdzenie wartości null. Jeśli odwołanie do obiektu ma wartość null, wywołanie someObject.equals(null)wywoła a NullPointerExceptionbez wprowadzania metody equals.
Dave Costa
2
@ColinD Zgadzam się, tylko pokazuję tutaj
Jigar Joshi
2
Zawsze zaleca się unikanie wartości null za wszelką cenę, więc w ogóle nie potrzebujesz sprawdzania wartości null;).
fwielstra
2
Zawsze możesz użyć Objects.equals(a, b)It nie zgłosi wyjątku NullPointerException, ale nadal zależy to od metody "równej" metody "a" i "b"
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.
głosuj za właściwą odpowiedź, która jest najbardziej użyteczna, w przeciwieństwie do oczywistej odpowiedzi „NullPointerException zostanie zwrócona” herp derp.
Ma to znaczenie, ponieważ equalsmoże tylko zwrócić falselub spowodować a NullPointerException(lub coś innego, jeśli zastąpiona equalsmetoda jest nonsensowna).
Tom
2
Jeśli użyjemy metody => .equals
if(obj.equals(null))// Which mean null.equals(null) when obj will be null.
Gdy twój obiekt będzie zerowy, zgłosi wyjątek punktu zerowego.
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.
Jak stwierdzono w JavaDoc (zawsze mądrze jest je przeczytać): Consequently, if both arguments are null, true is returned. ...:)
Thomas
1
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.
/**
* 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;}}
Problem polega na tym, że 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ć.
Tom
Przy okazji, Twoje pierwsze zdanie zawiera błędy gramatyczne i nie jest jasne, co masz na myśli. Czy masz na myśli „Oto przykład, gdzie str != nulli str.equals(null)powrócić truepodczas korzystania z org.json .”?
Tom
Myślę, że to dlatego, że jsonObjectzawiera klucz "field", dlatego fieldnie jest pusty, ma odniesienie, które zawiera json.org.JSONObject$Null obiekt
dina
Tak, ale nie traktowałbym Nulljak nulli "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.
Tom
0
Dlatego nigdy się nie mylę i unikam problemów z tym rozwiązaniem:
Dodatkowo pusty ciąg ( ""o długości 0) jest czymś zupełnie innym niż nullreferencja (tj. Brak łańcucha).
Thomas
0
Spotkałem się z tą sprawą zeszłej nocy.
Ustalam, że po prostu:
Nie istnieje metoda equals () dla null Więc nie możesz wywołać nieistniejącej metody jeśli nie masz
- >>> To jest powód dlaczego używamy == do sprawdzenia null
equals()
i zobaczyć. Kiedy spróbujesz, będzie to oczywisteOdpowiedzi:
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ą wnull
odwołaniu, otrzymasz plikNullPointerException
.Na przykład:
źródło
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()
nanull
dostanieszNullPointerException
Dlatego zawsze zaleca się sprawdzenie nieważności przed wywołaniem metody, gdziekolwiek ma to zastosowanie
Zobacz także
źródło
if ("hi".equals(str))
.someObject.equals(null)
wywoła aNullPointerException
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ę:
źródło
Objects.equals(null, null)
powrócitrue
- miej to na uwadze.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ą ==.
źródło
Co się stanie, jeśli foo jest zerowe?
Otrzymasz NullPointerException.
źródło
Jeśli zmienna Object ma wartość null, nie można wywołać na niej metody equals (), dlatego poprawne jest sprawdzenie odwołania do obiektu null.
źródło
Jeśli spróbujesz wywołać equals w odwołaniu do obiektu o wartości null, zostanie zgłoszony wyjątek wskaźnika o wartości null.
źródło
Według źródeł nie ma znaczenia, czego użyć do domyślnej implementacji metody:
Ale nie możesz być tego pewien
equals
w klasie niestandardowej.źródło
equals
może tylko zwrócićfalse
lub spowodować aNullPointerException
(lub coś innego, jeśli zastąpionaequals
metoda jest nonsensowna).Jeśli użyjemy metody => .equals
Gdy twój obiekt będzie zerowy, zgłosi wyjątek punktu zerowego.
więc powinniśmy użyć ==
porówna referencje.
źródło
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.
Przykładowy fragment powyżej zwróci wartość równą!
źródło
Consequently, if both arguments are null, true is returned. ...
:)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.
źródło
false
lubNullPointerException
(jeśliequals
nie zostanie zastąpiony czymś złym).tutaj jest przykład gdzie,
str != null
alestr.equals(null)
podczas używaniaorg.json
EDYCJA: oto klasa org.json.JSONObject $ Null :
źródło
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
istr.equals(null)
powrócićtrue
podczas korzystania z org.json .”?jsonObject
zawiera klucz "field", dlategofield
nie jest pusty, ma odniesienie, które zawierajson.org.JSONObject$Null
obiektNull
jaknull
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.Dlatego nigdy się nie mylę i unikam problemów z tym rozwiązaniem:
źródło
""
o długości 0) jest czymś zupełnie innym niżnull
referencja (tj. Brak łańcucha).Spotkałem się z tą sprawą zeszłej nocy.
Ustalam, że po prostu:
źródło
Twój kod łamie prawo Demeter. Dlatego lepiej zreformować sam projekt. Aby obejść ten problem, możesz użyć opcjonalnego
powyżej służy do sprawdzenia hierarchii obiektu, więc po prostu użyj
jeśli masz tylko jeden obiekt do sprawdzenia
Mam nadzieję że to pomoże !!!!
źródło
Zawsze możesz to zrobić
Spowoduje to najpierw sprawdzenie odwołania do obiektu, a następnie sprawdzenie samego obiektu, podając, że odwołanie nie jest null.
źródło
x.equals(null)
.