This article is participating in the Java Topic Month – Java Debug Notes event. See < activity link > for details.

Question: Avoid NullPointerExceptions in Java?

I use it a lot

Object ! =null
Copy the code

To avoid null-pointer exceptions, is there an alternative that can do the same for the following code

if(someobject ! =null) {
    someobject.doCalc();
}
Copy the code

Top answer: It seems to me that this is a fairly common problem that junior and mid-level developers tend to encounter at some point: they either don’t know or don’t trust the documentation of the project they’re working on, and defensively check for NULL. In addition, when writing their own code, they tend to rely on returning null values to represent something, and therefore require the caller to check for null values.

In other words, empty checks occur in two situations:

  • Null indicates a valid reply in the contract
  • If null, it is not a valid response.

The second can be resolved by using an assertion or by throwing a null-pointer exception.

Assertions are a new Java feature in 1.4 that is not widely used. Grammar:

assert

or

assert <condition> : <object>

Where <condition> is a Boolean expression, <object> is an object, and the output of their toString() method will be included in the error message.

An assert statement throws an Error. By default, Java ignores assertions. You can enable assertions by passing the option -EA to the JVM. You can enable and disable assertions for individual classes and packages. This means that you can use assertions to validate code during development and testing, and disable them in production, although my tests show little performance impact from assertions.

In this case, it’s ok not to use assertions, because the code will only fail, which is what happens when assertions are used. The only difference is that with assertions, it may happen earlier, in a more meaningful way, and may come with additional information that can help you figure out why it’s unexpected.

In the first case, which is a bit more difficult, if NULL is a valid response, it must be checked. Avoid using null as a response. Using the return collection approach is easy: avoid this problem by always returning an empty collection (or array) instead of null.

Without using an empty set, for example:

public interface Action {
  void doSomething(a);
}

public interface Parser {
  Action findAction(String userInput);
}
Copy the code

Here, the Parser takes input from the original user and finds the action to perform, perhaps when implementing a command line interface for a function. Now, if there is no proper operation, you can make the function return null. This leads to the empty check you are talking about.

Another solution is to never return null, and instead use the null Object pattern:

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething(a) { /* do nothing */}};public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      returnDO_NOTHING; }}}Copy the code

This is a much more concise way to write your code

It is entirely appropriate for the findAction () method to throw an Exception with a meaningful error message – especially in this case, where you are relying on user input. Throwing an exception to the findAction method is much better than a call method that throws a simple NullPointerException with no explanation.

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}
Copy the code

Alternatively, use some other operation instead of a try-catch

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething(a) {
            userConsole.err("Action not found: "+ userInput); }}}Copy the code