Sunday, 26 June 2011

Bad Habits with the equals() Method

I have this really bad habit, it’s something I know I shouldn't do, so this blog is to formally document my failing in the hope that I will change. This bad habit concerns the Java if statement and its use with the equals() method. Like me, most people, when comparing a string variable with a string constant would probably write something straight forward like this:

  private static String CHECK_VALUE = "Any old Value";

    String myValue = "hello";

    // This works, as myValue is not null
   
if (myValue.equals(CHECK_VALUE)) {
     
System.out.println("Your code goes here...");
   
}
We’d then think ‘What about null values?’ and add a separate null value check...

    myValue = null;

   
// To stop NullPointerExceptions use a null check
   
if ((myValue != null) && myValue.equals(CHECK_VALUE)) {
     
System.out.println("Your code goes here...");
   
}

...but this is confusing to read and all wrong. It’s better to call the equals() method on your constant passing in your possibly null value as an argument. That way the specification of the equals hashcode contract takes care of everything:

    // This does the same thing but more efficiently and cleanly
   
if (CHECK_VALUE.equals(myValue)) {
     
System.out.println("Your code goes here...");
   
}

Having written this down I’m now going to make a concerted effort to change my life...

1 comment:

ve said...

An r-value is a literal which can only go on the right side of assignment operation, e.g. in expression

a = 5;

a is an l-value, 5 is an r-value.

Thus it is a generally good practice to use r-value first in any comparison operation. First, it's gonna be a constant and hence no null, second, if you make a mistake in int comparison and write it down as an assignment, it will be caught by the compiler.

// hidden bug
if (a = 5) { ... }

// obvious bug
if (5 = a) { ...}