Categories
java null nullpointerexception

Avoiding NullPointerException in Java

4306

I use x != null to avoid NullPointerException. Is there an alternative?

if (x != null) {
    // ...
}

11

  • 138

    @Shervin Encouraging nulls makes the code less understandable and less reliable.

    Aug 2, 2010 at 9:17

  • 80

    Not using null is superior to most other suggestions here. Throw exceptions, don’t return or allow nulls. BTW – ‘assert’ keyword is useless, because it’s disabled by default. Use an always-enabled failure mechanism

    – ianpojman

    Jun 8, 2012 at 19:40


  • 3

    Nulls should be avoided in high-level code. Tony Hoare, who invented null references, calls them “a billion-dollar mistake”. Take a look here for some ideas.

    Apr 4, 2016 at 13:05

  • 3

    Seems to be in Java 8: static Objects.isNull(Object o) docs.oracle.com/javase/8/docs/api/java/util/Objects.html

    Jun 23, 2016 at 17:02


  • 5

    The most common misuse of null is people returning null instead of an empty collection. That drives me crazy each time. Stop using nulls, and you’ll live in a better world. Also, spread your code with final keyword and you’ll live in a even better world.

    – Jack

    Jun 29, 2021 at 9:22


2796

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. As of Java 1.7 you can use Objects.requireNonNull(foo). (If you are stuck with a previous version then assertions may be a good alternative.)

“Proper” usage of this method would be like below. The method returns the object passed into it and throws a NullPointerException if the object is null. This means that the returned value is always non-null. The method is primarily intended for validating parameters.

public Foo(Bar bar) {
    this.bar = Objects.requireNonNull(bar);
}

It can also be used like an assertion though since it throws an exception if the object is null. In both uses, a message can be added which will be shown in the exception. Below is using it like an assertion and providing a message.

Objects.requireNonNull(someobject, "if someobject is null then something is wrong");
someobject.doCalc();

Generally throwing a specific exception like NullPointerException when a value is null but shouldn’t be is favorable to throwing a more general exception like AssertionError. This is the approach the Java library takes; favoring NullPointerException over IllegalArgumentException when an argument is not allowed to be null.

(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);
        }
    }
}

3

  • 1

    Nice answer, especially mentioning asserts. I came from C and use them constantly. As to Null Objects, they are NOT a silver bullet. I have often spent hours debugging code which turned out to be a Null Object being used, doing nothing (or returning its defaults) when a NPE would have been indicated the problem much more clearly. So then you’ll have to do a “Null Object check” instead of a null check, and haven’t won anything, actually lost clarity. Nowadays, if I can’t avoid null, I just document it clearly and that’s it.

    – Franz D.

    Dec 25, 2021 at 0:01


  • Writing this.bar = Objects.requireNonNull(bar); is a good use of this method, because you’re not about to use this.bar. This way, you get the exception when an invalid null object is being passed, rather than when you try to use it. But, it often gets used this way: Objects.requireNonNull(getThing()).doThingStuff(); Here, the call to Objects.requireNonNull() doesn’t change the behavior at all, it throws the NPE either way. It is best used when you are saving an object for later use. In my second example, the exception is useful. It helps track down the bug.

    Jul 9 at 3:45


  • Should we suggest using exceptions for control flow though? While it’s technically a solution that works, programmers should remember that exceptions should only be used to catch unexpected situations. When validating a user’s input, invalid input should ideally not lead to exceptions being thrown.

    – Lee White

    Jul 12 at 12:34

698

If you use (or planning to use) a Java IDE like JetBrains IntelliJ IDEA, Eclipse or Netbeans or a tool like findbugs then you can use annotations to solve this problem.

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.

18

  • 130

    @NotNull, @Nullable and other nullness annotations are part of JSR 305. You can also use them to detect potential problems with tools like FindBugs.

    – Jacek S

    May 8, 2010 at 16:33


  • 33

    I find it strangely annoying that the @NotNull & @Nullable interfaces live in the package com.sun.istack.internal. (I guess I associate com.sun with warnings about using a proprietary API.)

    – Jonik

    Jun 30, 2011 at 23:33

  • 21

    code portability goes null with jetbrains.I would think twice(square) before tying down to ide level.Like Jacek S said they are part of JSR any way which I thought was JSR303 by the way.

    Sep 8, 2011 at 9:39

  • 12

    I really don’t think that using a custom compiler is a viable solution to this problem.

    Aug 19, 2012 at 8:24

  • 69

    The good thing about annotations, which @NotNull and @Nullable are is that they nicely degrade when the source code is built by a system that doesn’t understand them. So, in effect, the argument that the code is not portable may be invalid – if you use a system that supports and understands these annotations, you get the added benefit of stricter error checking, otherwise you get less of it but your code should still build fine, and the quality of your running program is THE SAME, because these annotations were not enforced at runtime anyway. Besides, all compilers are custom 😉

    – amn

    Mar 20, 2013 at 9:49

346

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.

12

  • 100

    What’s the point in throwing IllegalArgumentException? I think NullPointerException would be clearer, and that would also be thrown if you don’t do the null-check yourself. I’d either use assert or nothing at all.

    – Axel

    Aug 9, 2011 at 16:47

  • 24

    It’s unlikely that every other value than null is acceptable. You could have IllegalArgumentException, OutOfRageException etc etc. Sometimes this makes sense. Other times you end up creating a lot of exception classes that doesn’t add any value, then you just use IllegalArgumentException. It doesn’t makes sense to have one exception for null-input, and another one for everything else.

    – myplacedk

    Aug 15, 2011 at 12:26

  • 7

    Yes, I agree to fail-fast-principle, but in the example given above, the value is not passed on, but is the object on which a method shall be called. So it fails equallys fast, and adding a null check just to throw an exception that would be thrown anyway at the same time and place doesn’t seem to make debugging any easier.

    – Axel

    Aug 22, 2011 at 11:20

  • 8

    A security hole? The JDK is full of code like this. If you don’t want the user to see stacktraces, then just disable them. No one implied that the behaviour is not documented. MySQL is written in C where dereferencing null pointers is undefined behaviour, nothing like throwing an exception.

    – fgb

    Apr 8, 2013 at 0:39

  • 9

    throw new IllegalArgumentException("object==null")

    Apr 20, 2013 at 23:35