Der Vertrag in equals
Bezug auf null
lautet wie folgt:
Für jeden Nicht-Null - Referenzwert
x
,x.equals(null)
solltereturn false
.
Das ist ziemlich eigenartig, denn wenn o1 != null
und o2 == null
dann haben wir:
o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
Die Tatsache, dass o2.equals(o1) throws NullPointerException
das eine gute Sache ist, weil es uns vor Programmiererfehlern warnt. Und doch würde dieser Fehler nicht aufgefangen, wenn wir ihn aus verschiedenen Gründen o1.equals(o2)
einfach auf " Umschalten" umschalten würden, was stattdessen nur "stillschweigend fehlschlagen" würde.
Die Fragen sind also:
- Warum ist es eine gute Idee, die
o1.equals(o2)
solltereturn false
statt zu werfenNullPointerException
? - Wäre es eine schlechte Idee, wenn wir den Vertrag nach Möglichkeit so umschreiben, dass
anyObject.equals(null)
immerNullPointerException
stattdessen geworfen wird?
Im Vergleich zu Comparable
Im Gegensatz dazu steht im Comparable
Vertrag Folgendes:
Beachten Sie, dass dies
null
keine Instanz einer Klasse ist unde.compareTo(null)
eineNullPointerException
obwohle.equals(null)
zurückgegeben werden solltefalse
.
Wenn NullPointerException
es angemessen ist compareTo
, warum ist es nicht für equals
?
Verwandte Fragen
Ein rein semantisches Argument
Dies sind die tatsächlichen Wörter in der Object.equals(Object obj)
Dokumentation:
Gibt an, ob ein anderes Objekt diesem "gleich" ist.
Und was ist ein Objekt?
JLS 4.3.1 Objekte
Ein Objekt ist eine Klasseninstanz oder ein Array.
Die Referenzwerte (oft nur Referenzen ) sind Zeiger auf diese Objekte und eine spezielle
null
Referenz, die sich auf kein Objekt bezieht .
Mein Argument aus diesem Blickwinkel ist wirklich einfach.
equals
testet, ob ein anderes Objekt "gleich" istthis
null
Referenz gibt kein anderes Objekt für den Test- Deshalb
equals(null)
sollte werfenNullPointerException