Best way to check for null values in Java?
Asked Answered
M

19

123

Before calling a function of an object, I need to check if the object is null, to avoid throwing a NullPointerException.

What is the best way to go about this? I've considered these methods.
Which one is the best programming practice for Java?

// Method 1
if (foo != null) {
    if (foo.bar()) {
        etc...
    }
}

// Method 2
if (foo != null ? foo.bar() : false) {
    etc...
}

// Method 3
try {
    if (foo.bar()) {
        etc...
    }
} catch (NullPointerException e) {
}

// Method 4 -- Would this work, or would it still call foo.bar()?
if (foo != null && foo.bar()) {
    etc...
}
Murchison answered 25/6, 2013 at 16:8 Comment(9)
Never catch null pointer exceptions. It falls into the category of "Boneheaded Exceptions" blogs.msdn.com/b/ericlippert/archive/2008/09/10/…Lumbricalis
@NickFreeman I thought so, I just added that for clarity, thanks for explaining why thoughMurchison
Depending on your use case, it can also make sense to disallow null values for foo and throw a NullPointerException if a null foo is passed to your method.Interesting
1) The difference between 1 and 4 is a style choice and a micro optimization at best. 2) It doesn't really matter as long as you aren't allowing the exception to be thrown, instead of worrying about which is best to use, your time would be better spent on clear design/better algorithms.Lumbricalis
@Interesting An IllegalArgumentException should be used in that case instead.Lumbricalis
Sorry for so many comments. Another concept to look into would be the Null Object Pattern en.wikipedia.org/wiki/Null_Object_patternLumbricalis
@NickFreeman I disagree - See for example: https://mcmap.net/q/73182/-illegalargumentexception-or-nullpointerexception-for-a-null-parameter-closed - the standard (in the JDK, in guava and according to Effective Java) is to throw a NPE. Although IAE is admittedly also commonly used in such situations.Interesting
@NickFreeman Totally agree. The new link is located at ericlippert.com/2008/09/10/vexing-exceptions by the way.Ejective
If you just want to print out an object, you can use Objects.toString() - System.out.println("Object is " + Objects.toString(yourObj, "Custom null object string"));Jonejonell
H
161

Method 4 is best.

if(foo != null && foo.bar()) {
   someStuff();
}

will use short-circuit evaluation, meaning it ends if the first condition of a logical AND is false.

Headrest answered 25/6, 2013 at 16:11 Comment(3)
Thanks, I thought that would be best, but I wasn't sure why it wouldn't call the second condition, or if it might sometimes - thanks for explaining why.Murchison
Yes because you are using the short-circuit operand && so it won't finish the whole expressionGuest
@Arty-fishL that's always a good question since it's language dependent - USUALLY C-like languages tend to have short-circuit-left-to-right, but that's not the case for all languages, better always check first ;)Hatfield
I
19

The last and the best one. i.e LOGICAL AND

  if (foo != null && foo.bar()) {
    etc...
}

Because in logical &&

it is not necessary to know what the right hand side is, the result must be false

Prefer to read :Java logical operator short-circuiting

Infringement answered 25/6, 2013 at 16:10 Comment(1)
with this method I find myself getting operator && cannot be applied to boolean if (object.getObjectMethod() != null && object.getObjectMethod().getNextThing())Ambrosio
O
19

Since java 8 you can use Objects.nonNull(Object obj)

if(nonNull(foo)){ 
//
}
Olive answered 15/2, 2021 at 9:58 Comment(2)
This is available since Java 8.Cispadane
If you read the documentation of this method you will know that it is not supposed to be used in if statements, it is designed as a predicate for filtersEcdysis
D
7
  • Do not catch NullPointerException. That is a bad practice. It is better to ensure that the value is not null.
  • Method #4 will work for you. It will not evaluate the second condition, because Java has short-circuiting (i.e., subsequent conditions will not be evaluated if they do not change the end-result of the boolean expression). In this case, if the first expression of a logical AND evaluates to false, subsequent expressions do not need to be evaluated.
Drizzle answered 25/6, 2013 at 16:12 Comment(4)
Its worth mentioning why catching null pointer exceptions is bad practice; exceptions are really really expensive, even a few will really slow your codeFootpace
@RichardTingle in most cases the cost of an exception is neglible (java uses them all over the place) it is more that the NullpointerException could originate not only from foo but anywhere between try{ and }catch so you might hide a bug by catching itLyse
@Lyse The cost of doing (almost) anything once is negligible, its obviously only relevant if the section of code its in is a bottle neck; however if it is then its likely to be the cause. I collected some data in response to this question #16320514. Obviously its also a bad idea for the reasons you mention (any many others besides). Possibly I should have said "one of the reasons" rather than "the reason"Footpace
@RichardTingle exceptions are not as expensive as they used to be (especially if you do not need to inspect the stack trace). Except for that I agree - the reason for me, however, is that exceptions break the program flow as expected by a reader.Peden
E
5

Method 4 is far and away the best as it clearly indicates what will happen and uses the minimum of code.

Method 3 is just wrong on every level. You know the item may be null so it's not an exceptional situation it's something you should check for.

Method 2 is just making it more complicated than it needs to be.

Method 1 is just method 4 with an extra line of code.

Extrados answered 25/6, 2013 at 16:13 Comment(4)
Method 3 is what you'd normally do in Python. Rather than "You know the item may be null so it's not an exceptional situation" you could say "You know that in exceptional situations (like a file is missing somewhere) it will be null". I don't know why java developers are so afraid of exceptions. What's the point of adding exceptions capability to the language if you still have to check return values everywhere? Is there a performance penalty from surrounding code with try .. catch? Is there a good reason, or is it just Java style?Widthwise
@Widthwise Exceptions are expensive in Java at least when compared to a regular return. An exception has to capture a stack trace which is quite expensive although I vaguely remember that was optimised a few years ago for people that did use exceptions for flow of control. In Java it's common for an exception to be used for something exceptional, if you expect to read from a file and it's not there that's an exception. As for the null checking I somewhat agree and Java now has numerous ways of dealing with nulls such as the new Optional class.Extrados
On performance, I'm not interested in the performance of the exception happening - worst case it's a second or 2 before the user gets an error message - I'm interested in the performance of surrounding withtry { ... } catch vs if (foo != null) { ... }. Assuming the value is not null, is the explicit null check faster than the try catch, and does that hold if you e.g. have several things that can be null and you surround the whole thing with the try catch, or need the try catch for other errors and are adding an extra catch?Widthwise
The null check will be at least a thousand times faster (probably many thousands). For the path of execution to get into the catch block an exception has to have been raised which means generating a stack trace etc etc. I don't know for sure but the null check almost certainly drops to a native instruction so it's as close to instant as you can get. As long as there's no exception raised a try catch block has negligible performance impact.Extrados
A
5

In Java 7, you can use Objects.requireNonNull(). Add an import of Objects class from java.util.

public class FooClass {
    //...
    public void acceptFoo(Foo obj) {
        //If obj is null, NPE is thrown
        Objects.requireNonNull(obj).bar(); //or better requireNonNull(obj, "obj is null");
    }
    //...
}
Alfy answered 10/3, 2015 at 5:8 Comment(3)
Somehow SO doesn't allow me to add import java.util.Objects; line into the code, so putting it in comment here.Alfy
In case of Java 8 you can try using Optional class.Alfy
Will throw a NullPointer if it is NullRuin
I
4

As others have said #4 is the best method when not using a library method. However you should always put null on the left side of the comparison to ensure you don't accidentally assign null to foo in case of typo. In that case the compiler will catch the mistake.

// You meant to do this
if(foo != null){

// But you made a typo like this which will always evaluate to true
if(foo = null)

// Do the comparison in this way
if(null != foo)

// So if you make the mistake in this way the compiler will catch it
if(null = foo){

// obviously the typo is less obvious when doing an equality comparison but it's a good habit either way
if(foo == null){
if(foo =  null){
Interregnum answered 11/9, 2015 at 17:4 Comment(2)
(foo = null) does not evaluate to true.Imp
In Java, boolean is a type of it's own, and not an int, like in C or C++. So the Java compiler will notice when you use an int instead of a boolean, and then complain about type miss match.Troth
M
2

I would say method 4 is the most general idiom from the code that I've looked at. But this always feels a bit smelly to me. It assumes foo == null is the same as foo.bar() == false.

That doesn't always feel right to me.

Mispickel answered 25/6, 2013 at 16:13 Comment(0)
G
2

Method 4 is my preferred method. The short circuit of the && operator makes the code the most readable. Method 3, Catching NullPointerException, is frowned upon most of the time when a simple null check would suffice.

Girder answered 25/6, 2013 at 16:13 Comment(0)
C
2

Simple one line Code to check for null :

namVar == null ? codTdoForNul() : codTdoForFul();
Conviction answered 4/6, 2017 at 6:34 Comment(0)
A
2

You also can use ObjectUtils.isNotEmpty() to check if an Object is not empty and not null.

Affined answered 9/8, 2017 at 11:26 Comment(0)
E
2

Update

I created a java library(Maven Dependency) for the java developers to remove this NullPointerException Hell from their code. Check out my repository.

NullUtil Repository

Generic Method to handle Null Values in Java

<script src="https://gist.github.com/rcvaram/f1a1b89193baa1de39121386d5f865bc.js"></script>
  1. If that object is not null we are going to do the following things.

    a. We can mutate the object (I)

    b. We can return something(O) as output instead of mutating the object (I)

    c. we can do both

In this case, We need to pass a function which needs to take the input param(I) which is our object If we take it like that, then we can mutate that object if we want. and also that function may be something (O).

  1. If an object is null then we are going to do the following things

    a. We may throw an exception in a customized way

    b. We may return something.

In this case, the object is null so we need to supply the value or we may need to throw an exception.

I take two examples.

  1. If I want to execute trim in a String then that string should not be null. In that case, we have to additionally check the null value otherwise we will get NullPointerException
public String trimValue(String s){
   return s == null ? null : s.trim();
}
  1. Another function which I want to set a new value to object if that object is not null otherwise I want to throw a runtime exception.
public void setTeacherAge(Teacher teacher, int age){
   if (teacher != null){
      teacher.setAge(age);
   } else{
      throw new RuntimeException("teacher is null")
    }
}

With my Explanation, I have created a generic method that takes the value(value may be null), a function that will execute if the object is not null and another supplier function that will execute if the object is null.

GenericFunction

  public <I, O> O setNullCheckExecutor(I value, Function<I, O> nonNullExecutor, Supplier<O> nullExecutor) {
        return value != null ? nonNullExecutor.apply(value) : nullExecutor.get();
    }

So after having this generic function, we can do as follow for the example methods 1.

//To Trim a value
        String trimmedValue = setNullCheckExecutor(value, String::trim, () -> null);

Here, the nonNullExecutor Function is trim the value (Method Reference is used). nullExecutorFunction is will return null since It is an identity function.

2.

// mutate the object if not null otherwise throw a custom message runtime exception instead of NullPointerException
 setNullCheckExecutor(teacher, teacher -> {
            teacher.setAge(19);
            return null;
        }, () -> {
            throw new RuntimeException("Teacher is null");
        });
Electuary answered 2/12, 2021 at 14:8 Comment(0)
A
1

if you do not have an access to the commons apache library, the following probably will work ok

if(null != foo && foo.bar()) {
//do something
}
Avoidance answered 25/6, 2013 at 16:15 Comment(3)
The second snippet throws NPE when foo is null.Jerrine
Xaerxess, you're right, I removed the code snippet with the possible NPEAvoidance
if you do not have an access to the commons apache library which part of the library were you referring to?Comprehensive
A
1

If you control the API being called, consider using Guava's Optional class

More info here. Change your method to return an Optional<Boolean> instead of a Boolean.

This informs the calling code that it must account for the possibility of null, by calling one of the handy methods in Optional

Aniconic answered 25/6, 2013 at 16:58 Comment(0)
I
0

Your last proposal is the best.

if (foo != null && foo.bar()) {
    etc...
}

Because:

  1. It is easier to read.
  2. It is safe : foo.bar() will never be executed if foo == null.
  3. It prevents from bad practice such as catching NullPointerExceptions (most of the time due to a bug in your code)
  4. It should execute as fast or even faster than other methods (even though I think it should be almost impossible to notice it).
Indulgence answered 25/6, 2013 at 16:30 Comment(0)
Z
0

We can use Object.requireNonNull static method of Object class. Implementation is below

public void someMethod(SomeClass obj) {
    Objects.requireNonNull(obj, "Validation error, obj cannot be null");
}
Zacek answered 6/2, 2017 at 6:41 Comment(0)
A
0
public <T, U> U defaultGet(T supplier, Function<T, U> mapper, U defaultValue) {
        return Optional.ofNullable(supplier).map(mapper).orElse(defaultValue);

    }

You can create this function if you prefer function programming

Aga answered 2/8, 2021 at 19:26 Comment(1)
Welcome to StackOverflow, It will be good if you add some extra code snippets demonstrating your suggestion, which will help the answer seekers to get more insights from your answerMeuse
I
0

Allot of times I look for null when processing a function -

public static void doSomething(Object nullOrNestedObject) {
     if (nullOrNestedObject == null || nullOrNestedObject.getNestedObject()) {
        log.warn("Invalid argument !" );
        return;
        // Or throw an exception
        // throw new IllegalArgumentException("Invalid argument!");

     }
    nullOrNestedObject.getNestedObject().process()
     ... // Do other function stuff
}

That way if it is null it just stops execution early, and you don't have to nest all of your logic in an if.

Ist answered 8/9, 2022 at 13:46 Comment(0)
E
0

Since java 1.8, you can use Optional.ofNullable. This option will be good for more nested object.

You can use it like -

if (Optional.ofNullable(foo).map(Foo::bar).orElse(false)) {
    // TODO
}

Or -

if (Optional.ofNullable(foo).map(Foo::bar).ifPresent(bar -> {
    // TODO
});
Egwin answered 15/1 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.