Reputation: 131
I have created an equals method. I believe I can do it in two ways but java doesn't seem to agree. Here is the first example which I know works.
public class HelloWorld {
public boolean equals(Object rhs){
if(this==rhs){
return true;
}else if( rhs==null || this.getClass() != rhs.getClass()){
return false;
}else{
HelloWorld tmp =(HelloWorld)rhs;
return true;
}
}
public static void main(String[] args){
HelloWorld c = new HelloWorld();
System.out.println(c.equals(null));
}
}
And here is the second example which doesn't work. Instead of returning false I get a nullpointerexception.
public class HelloWorld {
public boolean equals(Object rhs){
if(this==rhs){
return true;
}else if(this.getClass() != rhs.getClass() || rhs==null){
return false;
}else{
HelloWorld tmp =(HelloWorld)rhs;
return true;
}
}
public static void main(String[] args){
HelloWorld c = new HelloWorld();
System.out.println(c.equals(null));
}
}
My question then... The only difference between the two pieces of code is that in the first piece I've written
rhs ==null ||...
And in the second piece it's on the other side of the OR-operator so
...|| rhs==null
Why would the first case not give me a Nullpointer but the second case does? Why should it matter on which side of the OR operator i write the boolean statement?
Upvotes: 3
Views: 123
Reputation: 384
As you are using '||' which is conditional OR with short-circuit behavior, the second condition is not been evaluated if the first comes out to be true.
For example if you are using (A||B) --- if A is true, B will not be evaluated.
that's why you are getting Null Pointer exception in case rhs is null.
The first set of code is actually correct as you are correctly handling Null case over there, which is not with the case of second set.
If you want both conditions to be evaluated and don't want to have short circuit behavior, you can use '|' operator instead of '||'.
So in case of (A|B) ---even if A is true, B will be evaluated.
Upvotes: 0
Reputation: 308763
I would recommend that you follow Joshua Bloch's recipe for proper implementation of the equals method from his "Effective Java" chapter 3.
If you implement equals, you should also implement hashCode.
Upvotes: 1
Reputation: 1500515
The right-hand side of the ||
operator isn't executed if the left-hand side evaluates to true
, as per JLS section 15.24:
The conditional-or operator
||
operator is like|
(§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand isfalse
.
So in your first case, rhs == null
evaluates to true, so rhs.getClass()
isn't executed - otherwise it would have thrown a NullPointerException
.
In your second case, you're executing rhs.getClass()
unconditionally, hence the exception.
If you use |
instead of ||
, you'll get an exception in both cases.
Upvotes: 2
Reputation: 178263
It matters because ||
, being the conditional "OR" operator, won't evaluate the right expression if the left expression is true
, because the result can already be determined. This is known as "short-circuit" behavior.
Section 15.24 of the JLS covers this:
The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.
The right hand expression is not evaluated, so the NullPointerException
is avoided.
(The &&
conditional "AND" operator, also "short circuits" and will only evaluate the right side if the left side is true
.)
Upvotes: 6