java - Avoiding != null statements


The idiom I use the most when programming in Java is to test if object != null before I use it. This is to avoid a NullPointerException. I find the code very ugly, and it becomes unreadable.

Is there a good alternative to this?

I want to address the necessity to test every object if you want to access a field or method of this object.

For example:

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

In this case I will avoid a NullPointerException, and I don't know exactly if the object is null or not. These tests appear throughout my code as a consequence.



Answers



This to me sounds like a reasonably common problem that junior to intermediate developers tend to face at some point: they either don't know or don't trust the contracts they are participating in and defensively overcheck for nulls. Additionally, when writing their own code, they tend to rely on returning nulls to indicate something thus requiring the caller to check for nulls.

To put this another way, there are two instances where null checking comes up:

  1. Where null is a valid response in terms of the contract; and

  2. Where it isn't a valid response.

(2) is easy. Either use assert statements (assertions) or allow failure (for example, NullPointerException). Assertions are a highly-underused Java feature that was added in 1.4. The syntax is:

assert <condition>

or

assert <condition> : <object>

where <condition> is a boolean expression and <object> is an object whose toString() method's output will be included in the error.

An assert statement throws an Error (AssertionError) if the condition is not true. 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 validate code with the assertions while developing and testing, and disable them in a production environment, although my testing has shown next to no performance impact from assertions.

Not using assertions in this case is OK because the code will just fail, which is what will happen if you use assertions. The only difference is that with assertions it might happen sooner, in a more-meaningful way and possibly with extra information, which may help you to figure out why it happened if you weren't expecting it.

(1) is a little harder. If you have no control over the code you're calling then you're stuck. If null is a valid response, you have to check for it.

If it's code that you do control, however (and this is often the case), then it's a different story. Avoid using nulls as a response. With methods that return collections, it's easy: return empty collections (or arrays) instead of nulls pretty much all the time.

With non-collections it might be harder. Consider this as an example: if you have these interfaces:

public interface Action {
  void doSomething();
}

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

where Parser takes raw user input and finds something to do, perhaps if you're implementing a command line interface for something. Now you might make the contract that it returns null if there's no appropriate action. That leads the null checking you're talking about.

An alternative 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() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

Compare:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

to

ParserFactory.getParser().findAction(someInput).doSomething();

which is a much better design because it leads to more concise code.

That said, perhaps 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. It would be much better for the findAction method to throw an Exception than for the calling method to blow up with a simple NullPointerException with no explanation.

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

Or if you think the try/catch mechanism is too ugly, rather than Do Nothing your default action should provide feedback to the user.

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



If you use (or planning to use) JetBrains IntelliJ IDEA, a Java IDE, you can use some particular annotations developed by them.

Basically, you've got @Nullable and @NotNull.

You can use in method and parameters, like this:

@NotNull public static String helloWorld() {
    return "Hello World";
}

or

@Nullable public static String helloWorld() {
    return "Hello World";
}

The second example won't compile (in IntelliJ IDEA).

When you use the first helloWorld() function in another piece of code:

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

Now the IntelliJ IDEA compiler will tell you that the check is useless, since the helloWorld() function won't return null, ever.

Using parameter

void someMethod(@NotNull someParameter) { }

if you write something like:

someMethod(null);

This won't compile.

Last example using @Nullable

@Nullable iWantToDestroyEverything() { return null; }

Doing this

iWantToDestroyEverything().something();

And you can be sure that this won't happen. :)

It's a nice way to let the compiler check something more than it usually does and to enforce your contracts to be stronger. Unfortunately, it's not supported by all the compilers.

In IntelliJ IDEA 10.5 and on, they added support for any other @Nullable @NotNull implementations.

See blog post More flexible and configurable @Nullable/@NotNull annotations.




If null-values are not allowed

If your method is called externally, start with something like this:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

Then, in the rest of that method, you'll know that object is not null.

If it is an internal method (not part of an API), just document that it cannot be null, and that's it.

Example:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

However, if your method just passes the value on, and the next method passes it on etc. it could get problematic. In that case you may want to check the argument as above.

If null is allowed

This really depends. If find that I often do something like this:

if (object == null) {
  // something
} else {
  // something else
}

So I branch, and do two completely different things. There is no ugly code snippet, because I really need to do two different things depending on the data. For example, should I work on the input, or should I calculate a good default value?


It's actually rare for me to use the idiom "if (object != null && ...".

It may be easier to give you examples, if you show examples of where you typically use the idiom.




What's the best way to avoid lots of “if (obj != null)” in Java code?

A first answer is to always return empty Lists, Sets, Arrays instead of null for method returning this kind of objects. Item 43 of Effective Java second edition from Joshua Bloch




Take a look at the Null Object Pattern. The basic idea is you have a special version of your class that you can use instead of null.

This special version has fields set to default values that make sense in your code. It means that you never have null references, you just have a class that doesn't do much or returns default values when used.




In my opinion, null checks are evil. They show that there is no contract that establishes whether obj may be null or not. The good alternative would be to write the code in such a way that obj is guaranteed never null. For example: if a getter must get a non-null obj, but cannot, it must throw an exception itself.




How avoid multiple IF loops in Java

Use &&. && is logical and. && combines two values and returns a boolean which is true if and only if both of its operands are true

if(address!=null && firstName!=null && lastName!=null)
{
}

For instance

boolean b;
b = 3 > 2 && 5 < 7; // b is true
b = 2 > 3 && 5 < 7; // b is now false



Use and operator (&&)

   if(address!=null && firstName!=null && lastName!=null) 
    {
      //DoSomething here 
    }

And I suggest you to see Short circuit evaluation




if loop is a wrong word. You should say if statements
As in you case you can use OR (||) or AND (&&)statement like this

if(address!=null && firstName!=null && lastName!=null)
{
}


Try AND(&&) if you want to pass all checks or intead of nested if statements and try OR(||) for non nested like else if or simply say if you want to pass anyone of your condition

But if all of these are Strings then you should try like this
"yourValue".equals(stringValue)
This will skip the null check.




How to avoid write code like “XXX!=null” or “XXX!=null || XXX.isEmpty”

The answer depends on whether null has a special meaning. For example for a String field does your application need to distinguish between null and ""? For a Collection-valued field does it need to distinguish between null and an empty collection object?

If the answer is "no", then you could write your "data object" classes to normalize the nulls to the respective "in band" values. You could do this in the getters or the setters or the constructors, depending on exactly how the objects are materialized from the database.

A couple of other things you could do are:

  • Change the database schema to make the respective columns "not null".

  • If you are using an ORM or a data binding mechanism, try to configure that (via annotations or whatever) to use the "in band" values instead of null.

The point of turning null into "" or an empty array or collection is that you don't need to treat the "in band" value as a special case ... unless the business logic of your application specifically requires this.

In short, if you stamp out the null values systematically, you don't need to test for them in the business logic.


Note that this approach doesn't always work. The case that annoys me is fetching parameters from an HTTPRequest object in a servlet:

  • The application potentially has to deal with 4 distinct cases:

    • parameter not present

    • parameter present with no value / an empty value

    • parameter present with a non-empty value

    • parameter present multiple times.

  • The parameters are being fetched from a standard API rather than a custom class that could be made to normalize the values according to the webapp's requirements.







You can write a function that checks if an object is null and/or if it's a String, is it "". Then simply call that function each time you would need to check all of the conditions. Make it return a boolean so that you can just insert it in the if statements.

boolean check(Object o)
{
    if (o != null)
        {
            if (o instanceof String)
            {
                if (((String) o).equals(""))
                    return false;
            }
            return true;
        }
        return false;
}

Refer to rcook's suggestion in the comments for a better implementation of this.