The contract of equals with regards to null, is as follows:
For any non-null reference value
x,x.equals(null)shouldreturn false.
This is rather peculiar, because if o1 != null and o2 == null, then we have:
o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
The fact that o2.equals(o1) throws NullPointerException is a good thing, because it alerts us of programmer error. And yet, that error would not be catched if for various reasons we just switched it around to o1.equals(o2), which would just "silently fail" instead.
So the questions are:
- Why is it a good idea that
o1.equals(o2)shouldreturn falseinstead of throwingNullPointerException? - Would it be a bad idea if wherever possible we rewrite the contract so that
anyObject.equals(null)always throwNullPointerExceptioninstead?
On comparison with Comparable
In contrast, this is what the Comparable contract says:
Note that
nullis not an instance of any class, ande.compareTo(null)should throw aNullPointerExceptioneven thoughe.equals(null)returnsfalse.
If NullPointerException is appropriate for compareTo, why isn't it for equals?
Related questions
A purely semantical argument
These are the actual words in the Object.equals(Object obj) documentation:
Indicates whether some other object is "equal to" this one.
And what is an object?
JLS 4.3.1 Objects
An object is a class instance or an array.
The reference values (often just references) are pointers to these objects, and a special
nullreference, which refers to no object.
My argument from this angle is really simple.
equalstests whether some other object is "equal to"thisnullreference gives no other object for the test- Therefore,
equals(null)should throwNullPointerException