Am einfachsten ist es, die Nullprüfung zu überprüfen equals()und zu sehen. Wenn Sie es versuchen, wird es sofort offensichtlich sein
Goran Jovic
Übrigens, eine Google-Suche mit den Schlüsselwörtern "Java Null Check" (ohne Anführungszeichen) gab mir als einer der Top-Hits diesen Thread , der die gleichen Informationen wie die Antworten hier hat.
Mitch Schwartz
Antworten:
179
Das sind zwei völlig verschiedene Dinge. ==vergleicht die Objektreferenz, falls vorhanden, die in einer Variablen enthalten ist. .equals()prüft, ob zwei Objekte gemäß ihrem Vertrag gleich sind, was Gleichheit bedeutet. Es ist durchaus möglich, dass zwei unterschiedliche Objektinstanzen gemäß ihrem Vertrag "gleich" sind. Und dann gibt es noch das kleine Detail, dass equalses sich um eine Methode handelt. Wenn Sie versuchen, sie für eine nullReferenz aufzurufen , erhalten Sie eine NullPointerException.
Zum Beispiel:
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: Nein, ich erstelle im Allgemeinen keine öffentlichen Felder (obwohl es für dieses Beispiel so oder so nicht wirklich wichtig ist). Warum?
TJ Crowder
@TJ Crowder "Das sind zwei völlig verschiedene Dinge ..." im Allgemeinen ja. Die Standardimplementierung von beiden ist jedoch dieselbe, wenn mein Verständnis korrekt ist. Mit Blick auf den Quellcode führt .equals () im Grunde genommen eine == Prüfung durch. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
Ayush
1
@ Ayush - Das ist die Standardeinstellung in Object, ja. Es wird jedoch von einer großen Anzahl der JDK-Klassen überschrieben. Aber es geht nicht um Implementierung, sondern um Semantik. (Randnotiz: JDK7 ist sehr veraltet.)
TJ Crowder
Richtig, das macht Sinn, wollte nur klarstellen.
Ayush
38
wenn Sie rufen .equals()auf , nulldie Sie erhaltenNullPointerException
Es ist daher immer ratsam, die Nichtigkeit zu überprüfen, bevor Sie die Methode aufrufen, wo immer sie gilt
Ihr Beispiel ist im Allgemeinen besser geschrieben als if ("hi".equals(str)).
ColinD
3
@ user368186: Es geht nicht darum, ob die Methode equals eine Nullprüfung enthält. Wenn Ihre Objektreferenz null ist, löst der Aufruf someObject.equals(null)ein aus, NullPointerExceptionohne jemals die Methode equals einzugeben.
Dave Costa
2
@ColinD Stimmen Sie zu, nur hier zu demonstrieren
Jigar Joshi
2
Es ist immer ratsam, Nullen um jeden Preis zu vermeiden, damit Sie überhaupt keine Nullprüfungen benötigen;).
Fwielstra
2
Sie können immer verwenden Objects.equals(a, b)Es wird keine NullPointerException auslösen, aber es hängt immer noch von der "gleichen" Methode der "a" und "b" ab
Seit Java 1.7 empfehle ich diese Funktion, wenn Sie zwei Objekte vergleichen möchten, die möglicherweise null sind:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Diese Klasse besteht aus statischen Dienstprogrammmethoden für die Bearbeitung von Objekten. Diese Dienstprogramme umfassen null-sichere oder null-tolerante Methoden zum Berechnen des Hash-Codes eines Objekts, zum Zurückgeben einer Zeichenfolge für ein Objekt und zum Vergleichen zweier Objekte.
Nur um es für andere sichtbarer zu machen (siehe Antwort von chin90 oder JavaDoc ): Objects.equals(null, null)wird zurückkehren true- denken Sie daran.
Thomas
20
In Java sind 0 oder null einfache Typen und keine Objekte.
Die Methode equals () ist nicht für einfache Typen erstellt. Einfache Typen können mit == abgeglichen werden.
upvote für die eigentliche Antwort, die am nützlichsten ist, im Gegensatz zu der offensichtlichen "NullPointerException wird zurückgegeben" herp derp Antwort.
Es ist wichtig, da equalsnur zurückkehren falseoder ein verursachen kann NullPointerException(oder etwas anderes, wenn die Überschreibungsmethode equalsUnsinn ist).
Tom
2
Wenn wir die Methode => .equals verwenden
if(obj.equals(null))// Which mean null.equals(null) when obj will be null.
Wenn Ihr Objekt null ist, wird eine Nullpunktausnahme ausgelöst.
Object.equals ist null-sicher. Beachten Sie jedoch, dass object.equals true zurückgibt, wenn zwei Objekte null sind. Überprüfen Sie daher, ob die zu vergleichenden Objekte nicht null sind (oder Nullwerte enthalten), bevor Sie object.equals für verwenden Vergleich.
Wie vom JavaDoc angegeben (es ist immer ratsam, diese zu lesen): Consequently, if both arguments are null, true is returned. ...:)
Thomas
1
Da gleich eine von der Objektklasse abgeleitete Funktion ist, vergleicht diese Funktion Elemente der Klasse. Wenn Sie es mit null verwenden, wird false zurückgegeben, da der Klasseninhalt nicht null ist. Außerdem vergleicht == die Referenz auf ein Objekt.
/**
* 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;}}
Das Problem hierbei ist, dass field.equals(null)true zurückgegeben wird. Dies bricht das übliche Java-Verhalten und ist daher verwirrend. field.equals("null")Zumindest aus meiner Sicht sollte es nur funktionieren . Ich weiß nicht, warum die Bibliotheksentwickler dachten, dass dies gut zu unterstützen wäre.
Tom
Übrigens hat Ihr erster Satz ein Grammatikproblem und es ist unklar, was Sie damit meinen. Meinen Sie "Hier ist ein Beispiel, wo str != nullund str.equals(null)kehren Sie zurück, truewenn Sie org.json verwenden ."?
Tom
Ich denke, das liegt daran, dass der jsonObjectSchlüssel "Feld" enthält, weshalb er fieldnicht null ist. Er hat eine Referenz, die das json.org.JSONObject$Null Objekt enthält
dina
Ja, aber ich würde nicht Nullgerne behandeln nullund "null"stattdessen verwenden. Aber ich denke, sie haben das getan, um zu vermeiden, dass Strings benötigt werden. Aber auch mit dieser Bibliothek field.equals(null)ist fast immer noch ein Thema: P.
Tom
0
So werde ich nie verwirrt und vermeide Probleme mit dieser Lösung:
Außerdem ist eine leere Zeichenfolge ( ""mit der Länge 0) etwas völlig anderes als eine nullReferenz (dh keine Zeichenfolge).
Thomas
0
Ich bin gestern Abend auf diesen Fall gestoßen.
Ich bestimme das einfach so:
Gibt es nicht equals () Methode für null So können Sie nicht invoke eine inexistent Methode , wenn Sie nicht haben
- >>> Das ist Grund dafür , warum wir verwenden == überprüfen null
equals()
und zu sehen. Wenn Sie es versuchen, wird es sofort offensichtlich seinAntworten:
Das sind zwei völlig verschiedene Dinge.
==
vergleicht die Objektreferenz, falls vorhanden, die in einer Variablen enthalten ist..equals()
prüft, ob zwei Objekte gemäß ihrem Vertrag gleich sind, was Gleichheit bedeutet. Es ist durchaus möglich, dass zwei unterschiedliche Objektinstanzen gemäß ihrem Vertrag "gleich" sind. Und dann gibt es noch das kleine Detail, dassequals
es sich um eine Methode handelt. Wenn Sie versuchen, sie für einenull
Referenz aufzurufen , erhalten Sie eineNullPointerException
.Zum Beispiel:
quelle
public int data
?Object
, ja. Es wird jedoch von einer großen Anzahl der JDK-Klassen überschrieben. Aber es geht nicht um Implementierung, sondern um Semantik. (Randnotiz: JDK7 ist sehr veraltet.)wenn Sie rufen
.equals()
auf ,null
die Sie erhaltenNullPointerException
Es ist daher immer ratsam, die Nichtigkeit zu überprüfen, bevor Sie die Methode aufrufen, wo immer sie gilt
Siehe auch
quelle
if ("hi".equals(str))
.someObject.equals(null)
ein aus,NullPointerException
ohne jemals die Methode equals einzugeben.Objects.equals(a, b)
Es wird keine NullPointerException auslösen, aber es hängt immer noch von der "gleichen" Methode der "a" und "b" abZusätzlich zur akzeptierten Antwort ( https://stackoverflow.com/a/4501084/6276704 ):
Seit Java 1.7 empfehle ich diese Funktion, wenn Sie zwei Objekte vergleichen möchten, die möglicherweise null sind:
quelle
Objects.equals(null, null)
wird zurückkehrentrue
- denken Sie daran.In Java sind 0 oder null einfache Typen und keine Objekte.
Die Methode equals () ist nicht für einfache Typen erstellt. Einfache Typen können mit == abgeglichen werden.
quelle
Was passiert, wenn foo null ist?
Sie erhalten eine NullPointerException.
quelle
Wenn eine Objektvariable null ist, kann keine equals () -Methode aufgerufen werden, daher ist eine Objektreferenzprüfung von null korrekt.
quelle
Wenn Sie versuchen, bei einer Nullobjektreferenz gleich aufzurufen, wird eine Nullzeigerausnahme ausgelöst.
quelle
Laut Quellen spielt es keine Rolle, was für die Implementierung der Standardmethode verwendet werden soll:
equals
In der benutzerdefinierten Klasse können Sie sich jedoch nicht sicher sein .quelle
equals
nur zurückkehrenfalse
oder ein verursachen kannNullPointerException
(oder etwas anderes, wenn die Überschreibungsmethodeequals
Unsinn ist).Wenn wir die Methode => .equals verwenden
Wenn Ihr Objekt null ist, wird eine Nullpunktausnahme ausgelöst.
also sollten wir == verwenden
Es werden die Referenzen verglichen.
quelle
Object.equals ist null-sicher. Beachten Sie jedoch, dass object.equals true zurückgibt, wenn zwei Objekte null sind. Überprüfen Sie daher, ob die zu vergleichenden Objekte nicht null sind (oder Nullwerte enthalten), bevor Sie object.equals für verwenden Vergleich.
Das obige Beispiel-Snippet gibt gleich zurück!
quelle
Consequently, if both arguments are null, true is returned. ...
:)Da gleich eine von der Objektklasse abgeleitete Funktion ist, vergleicht diese Funktion Elemente der Klasse. Wenn Sie es mit null verwenden, wird false zurückgegeben, da der Klasseninhalt nicht null ist. Außerdem vergleicht == die Referenz auf ein Objekt.
quelle
false
oderNullPointerException
(wennequals
es nicht zu etwas Schlechtem überschrieben wird).Hier ist ein Beispiel, wo
str != null
aberstr.equals(null)
bei der Verwendungorg.json
BEARBEITEN: Hier ist die org.json.JSONObject $ Null- Klasse:
quelle
field.equals(null)
true zurückgegeben wird. Dies bricht das übliche Java-Verhalten und ist daher verwirrend.field.equals("null")
Zumindest aus meiner Sicht sollte es nur funktionieren . Ich weiß nicht, warum die Bibliotheksentwickler dachten, dass dies gut zu unterstützen wäre.str != null
undstr.equals(null)
kehren Sie zurück,true
wenn Sie org.json verwenden ."?jsonObject
Schlüssel "Feld" enthält, weshalb erfield
nicht null ist. Er hat eine Referenz, die dasjson.org.JSONObject$Null
Objekt enthältNull
gerne behandelnnull
und"null"
stattdessen verwenden. Aber ich denke, sie haben das getan, um zu vermeiden, dass Strings benötigt werden. Aber auch mit dieser Bibliothekfield.equals(null)
ist fast immer noch ein Thema: P.So werde ich nie verwirrt und vermeide Probleme mit dieser Lösung:
quelle
""
mit der Länge 0) etwas völlig anderes als einenull
Referenz (dh keine Zeichenfolge).Ich bin gestern Abend auf diesen Fall gestoßen.
Ich bestimme das einfach so:
quelle
Ihr Code verstößt gegen Demeters Gesetz. Deshalb ist es besser, das Design selbst zu überarbeiten. Als Problemumgehung können Sie Optional verwenden
oben ist die Hierarchie eines Objekts zu überprüfen, also einfach verwenden
wenn Sie nur ein Objekt überprüfen müssen
Hoffe das hilft !!!!
quelle
Das kannst du immer tun
Dadurch wird zuerst die Objektreferenz und dann das Objekt selbst überprüft, sofern die Referenz nicht null ist.
quelle
x.equals(null)
.