Is it a bad idea if equals(null) throws NullPointerException instead?
The contract of equals
with regards to null
, is as follows:
For any non-null reference value x
, x.equals(null)
should return 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:
o1.equals(o2)
should return false
instead of throwing NullPointerException
? anyObject.equals(null)
always throw NullPointerException
instead? On comparison with Comparable
In contrast, this is what the Comparable
contract says:
Note that null
is not an instance of any class, and e.compareTo(null)
should throw a NullPointerException
even though e.equals(null)
returns false
.
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 null
reference, which refers to no object.
My argument from this angle is really simple.
equals
tests whether some other object is "equal to" this
null
reference gives no other object for the test equals(null)
should throw NullPointerException
To the question of whether this asymmetry is inconsistent, I think not, and I refer you to this ancient Zen kōan:
At that moment, the compiler reached enlightenment.
An exception really should be an exceptional situation. A null pointer might not be a programmer error.
You quoted the existing contract. If you decide to go against convention, after all this time, when every Java developer expects equals to return false, you'll be doing something unexpected and unwelcome that will make your class a pariah.
I could't disagree more. I would not rewrite equals to throw an exception all the time. I'd replace any class that did that if I were its client.
Think of how .equals is related to == and .compareTo is related to the comparison operators >, <, >=, <=.
If you're going to argue that using .equals to compare an object to null should throw a NPE, then you'd have to say that this code should throw one as well:
Object o1 = new Object();
Object o2 = null;
boolean b = (o1 == o2); // should throw NPE here!
The difference between o1.equals(o2) and o2.equals(o1) is that in the first case you're comparing something to null, similar to o1 == o2, while in the second case, the equals method is never actually executed so there's no comparison happening at all.
Regarding the .compareTo contract, comparing a non-null object with a null object is like trying do this:
int j = 0;
if(j > null) {
...
}
Obviously this won't compile. You can use auto-unboxing to make it compile, but you get a NPE when you do the comparison, which is consistent with the .compareTo contract:
Integer i = null;
int j = 0;
if(j > i) { // NPE
...
}
链接地址: http://www.djcxy.com/p/13312.html