Java Tip: Testing String Equality

Mar12

This article is part of an ongoing series entitled Java Tips: Writing Better Code.

Summary: This tip will show you a better way of comparing Java Strings with literal values.

Java Strings are object types rather than primitive types. This means that when you test the value of a String in Java you should use the .equals() method rather than the == operator. Here’s an example that determines what Pennsylvanians eat for lunch:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class StringEquality
{
  public static void main(String[] args)
  {
    String city = "Pittsburgh";
    if (city.equals("Pittsburgh"))
    {
      System.out.println("Your sandwiches contain french fries.");
    }
    else if (city.equals("Philadelphia"))
    {
      System.out.println("Your sandwiches contain steak and cheese.");
    }
    else
    {
      System.out.println("I have no idea what you like to eat.");
    }
  }
}
$ java StringEquality
Your sandwiches contain french fries.

This code works just fine most of the time. However, what would happen if the city variable contained a null value? (Note: In this code example the city variable was hard coded to be null for simplicity’s sake. I’ll leave it to your good imagination to picture a real world scenario where a value might be null.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class StringEquality
{
  public static void main(String[] args)
  {
    String city = null;
    if (city.equals("Pittsburgh"))
    {
      System.out.println("Your sandwiches contain french fries.");
    }
    else if (city.equals("Philadelphia"))
    {
      System.out.println("Your sandwiches contain steak and cheese.");
    }
    else
    {
      System.out.println("I have no idea what you like to eat.");
    }
  }
}
$ java StringEquality
Exception in thread "main" java.lang.NullPointerException
	at StringEquality.main(StringEquality.java:10)

The problem with this code is that it is attempting to invoke a method on a null object reference. So, what’s a developer to do? Well, let’s start with a peek at what not to do. I was recently working with a not-to-be-named 3rd party’s code and came across null checks that looked something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class StringEquality
{
  public static void main(String[] args)
  {
    String city = null;
    if (city != null && city.equals("Pittsburgh"))
    {
      System.out.println("Your sandwiches contain french fries.");
    }
    else if (city != null && city.equals("Philadelphia"))
    {
      System.out.println("Your sandwiches contain steak and cheese.");
    }
    else
    {
      System.out.println("I have no idea what you like to eat.");
    }
  }
}

Although this approach certainly works, it’s very unwieldy and inefficient to perform a null check every time you test a String’s value. The simple solution to avoid null checks is to flip the order of the String variable and the String literal so that city.equals("Pittsburgh") becomes "Pittsburgh".equals(city). With this approach the equals method is invoked on the String literal rather than the String variable. Since String literals can’t be null by definition, you’ll never have to worry about NullPointerExceptions on String comparisons again

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class StringEquality
{
  public static void main(String[] args)
  {
    String city = null;
    if ("Pittsburgh".equals(city))
    {
      System.out.println("Your sandwiches contain french fries.");
    }
    else if ("Philadelphia".equals(city))
    {
      System.out.println("Your sandwiches contain steak and cheese.");
    }
    else
    {
      System.out.println("I have no idea what you like to eat.");
    }
  }
}
$ java StringEquality
I have no idea what you like to eat.