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
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.
In my previous post, Don’t Break The Back Button, I explained the difference between URL changing “horizontal” links and Ajax’s non-URL changing “vertical” links. If you haven’t already read that post, I encourage you to do so before reading this one.
In addition to potentially breaking the back button, Ajax’s vertical links can ruin a browser’s ability to link to the current resource. This is very similar to the way in which HTTP POST requests can’t be bookmarked in the same way as HTTP GET requests since they don’t include any query data in the URL.
Not only will this problem frustrate users who are interested in coming back to your web site; it will also make it difficult or impossible for search engines to properly link to your second-tier resources. Continue Reading »
The foundation of the web has been the hyperlink from one page to another. The links between pages have been primarily bi-directional, in the sense that visiting page A and then clicking on a link to page B would in no way prevent the user from either following a link back to page A or clicking the back button to get there. The chain of pages represented in the browser history each have a unique URL associated with them. In code we might store these URLs as a stack. Continue Reading »