428

I have noted that many Java 8 methods in Oracle JDK use Objects.requireNonNull(), which internally throws NullPointerException if the given object (argument) is null.

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

But NullPointerException will be thrown anyway if a null object is dereferenced. So, why should one do this extra null check and throw NullPointerException?

One obvious answer (or benefit) is that it makes code more readable and I agree. I'm keen to know any other reasons for using Objects.requireNonNull() in the beginning of the method.

Saleh
  • 1,819
  • 1
  • 17
  • 44
user4686046
  • 4,371
  • 2
  • 11
  • 7
  • 42
    https://en.wikipedia.org/wiki/Fail-fast – luk2302 Aug 11 '17 at 10:27
  • 4
    Possible duplicate of [Why explicitly throw a NullPointerException rather than letting it happen naturally?](https://stackoverflow.com/questions/43928556/why-explicitly-throw-a-nullpointerexception-rather-than-letting-it-happen-natura) – Hulk Aug 11 '17 at 13:32
  • 4
    That approach to argument checking lets you cheat when you're writing unit tests. Spring also has utilities like that (see https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/Assert.html ). If you have an "if" and want to have high unit test coverage, you have to cover both branches: when condition is met, and when condition is not met. If you use `Objects.requireNonNull`, your code has no branching so a single pass of a unit test will get you 100% coverage :-) – xorcus Apr 10 '20 at 20:07
  • [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) – Johannes Kuhn Nov 04 '20 at 15:03
  • all the explanations provided below are valid but in my opinion, I would look into why the method is receiving null in first place. I don't think is good practice to defensively check the inputs for null, it's better in my opinion to make sure the callers don't pass nulls. – javing Jan 14 '21 at 11:33
  • @javing Well how are you going make sure nobody passes null without making sure bad things happen when they try it? – SamB Jul 31 '21 at 21:57
  • I'm here because IntelliJ advises to use `requireNonNull` everywhere. If the examples below can make sense, I've to admit that the fixes advised by IntelliJ not always make – Christian Vincenzo Traina Oct 20 '22 at 08:12

12 Answers12

389

Because you can make things explicit by doing so. Like:

public class Foo {
  private final Bar bar;

  public Foo(Bar bar) {
    Objects.requireNonNull(bar, "bar must not be null");
    this.bar = bar;
  }

Or shorter:

  this.bar = Objects.requireNonNull(bar, "bar must not be null");

Now you know:

  • when a Foo object was successfully created using new()
  • then its bar field is guaranteed be non-null.

Compare that to: you create a Foo object today, and tomorrow you invoke a method that uses that field and throws. Most likely, you will not know tomorrow why that reference was null yesterday when it got passed to the constructor!

In other words: by explicitly using this method to check incoming references you can control the point in time when the exception will be thrown. And most of the time, you want to fail as fast as possible!

The major advantages are:

  • as said, controlled behavior
  • easier debugging - because you throw up in the context of the object creation. At a point in time where you have a certain chance that your logs/traces tell you what went wrong!
  • and as shown above: the true power of this idea unfolds in conjunction with final fields. Because now any other code in your class can safely assume that bar isn't null - and thus you do not need any if (bar == null) checks in other places!
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 50
    You can make your code more compact by writing `this.bar = Objects.requireNonNull(bar, "bar must not be null");` – Kirill Rakhman Aug 15 '17 at 13:44
  • 6
    @KirillRakhman Teaching GhostCat something cool I didn't know about --> winning a ticket in the GhostCat upvote lottery. – GhostCat Aug 15 '17 at 13:49
  • 2
    I think comment #1 here is the actual benefit of `Objects.requireNonNull(bar, "bar must not be null");`. Thanks for this one. – Kawu Dec 04 '18 at 10:08
  • @Kawu Sure, that is why I edited my answer back then to include that thing, which I didnt know either, or any of the people in my team ;-) – GhostCat Dec 04 '18 at 10:16
  • Sure if fail fast is what we are going for we can still use something like guava's `com.google.common.base.Preconditions#checkNotNull(T)` which of course you need to add the guava library, but why can't they follow the guava convention and throw an `IllegalArgumentException` – Mushtaq Jameel Feb 24 '19 at 09:39
  • 1
    Which one was first, and why should "the language" people follow the authors of *some* library?! Why doesn't guava follow the Java lang behavior?! – GhostCat Feb 24 '19 at 09:44
  • 6
    The `this.bar = Objects.requireNonNull(bar, "bar must not be null");` is ok in constructors, but potentially dangerous in other methods if two or more variables are set in the same method. Example: https://talkwards.com/2018/11/03/one-thing-to-avoid-when-using-objects-requirenonnull-in-java-8/ – Erk Jul 15 '19 at 19:32
  • 4
    Since `Objects.requireNonNull` is a static method, a static import can be done to make the code even shorter and easier to read: `this.bar = requireNonNull(...)`. – maxime.bochon Sep 07 '20 at 15:17
  • for decency, please review the documentation. in no shape or form this method is described to be safe for nullability. In fact, this method is a last resource to explain the object has been checked not to be null.. – Juan Mendez Jul 11 '23 at 20:31
  • @JuanMendez I have no idea what your comment is supposed to mean. I am explaining that you use this method to check for objects to not be null, and when you use it to check your constructor arguments before assigning the value to a **final** field of the class, of course that field is guaranteed to be not null afterwards. – GhostCat Jul 14 '23 at 05:54
  • this method is NOT checking an object is not null. this method ASSERTS the object is not null, but if it is null then you will get an null pointer exception. – Juan Mendez Jul 18 '23 at 02:24
  • Remember the question that was asked here. *you can control the point in time when the exception will be thrown* clearly states that this is about WHEN the null reference is communicated via an exception. There are only two paths to deal with null references: either to silently accept them, or to throw an exception. So, yes, asserting isn't checking, but the whole point of the exercise is to end up with either an exception, or a guaranteed to be not-null value. – GhostCat Jul 18 '23 at 13:56
172

Fail-fast

The code should crash as soon as possible. It should not do half of the work, dereference the null and only then crash, leaving half of some work done causing the system to be in an invalid state.

This is commonly called "fail early" or "fail-fast".

luk2302
  • 55,258
  • 23
  • 97
  • 137
53

But NullPointerException will be thrown anyway if a null object is dereferenced. So, why should one do this extra null check and throw NullPointerException?

It means you detect the problem immediately and reliably.

Consider:

  • The reference may not be used until later in the method, after your code has already performed some side-effects
  • The reference may not be dereferenced in this method at all
    • It could be passed to completely different code (i.e. cause and error are far apart in code space)
    • It could be used much later (i.e. cause and error are far apart in time)
  • It may be used somewhere that a null reference is valid, but has an unintended effect

.NET makes this better by separating NullReferenceException ("you dereferenced a null value") from ArgumentNullException ("you shouldn't have passed in null as an argument - and it was for this parameter). I wish Java did the same thing, but even with just a NullPointerException, it's still much easier to fix code if the error is thrown at the earliest point at which it can be detected.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
27

Using requireNonNull() as first statements in a method allow to identify right now/fast the cause of the exception.
The stacktrace indicates clearly that the exception was thrown as soon as the entry of the method because the caller didn't respect the requirements/contract. Passing a null object to another method may indeed provoke an exception at a time but the cause of the problem may be more complicated to understand as the exception will be thrown in a specific invocation on the null object that may be much further.


Here is a concrete and real example that shows why we have to favor fail fast in general and more particularly using Object.requireNonNull() or any way to perform a no null check on parameters designed to be not null.

Suppose a Dictionary class that composes a LookupService and a List of String representing words contained in. These fields are designed to be not null and one of these is passed in the Dictionary constructor.

Now suppose a "bad" implementation of Dictionary without null check in the method entry (here that is the constructor):

public class Dictionary {

    private final List<String> words;
    private final LookupService lookupService;

    public Dictionary(List<String> words) {
        this.words = this.words;
        this.lookupService = new LookupService(words);
    }

    public boolean isFirstElement(String userData) {
        return lookupService.isFirstElement(userData);
    }        
}


public class LookupService {

    List<String> words;

    public LookupService(List<String> words) {
        this.words = words;
    }

    public boolean isFirstElement(String userData) {
        return words.get(0).contains(userData);
    }
}

Now, let's invoke the Dictionary constructor with a null reference for the words parameter :

Dictionary dictionary = new Dictionary(null); 

// exception thrown lately : only in the next statement
boolean isFirstElement = dictionary.isFirstElement("anyThing");

The JVM throws the NPE at this statement :

return words.get(0).contains(userData); 
Exception in thread "main" java.lang.NullPointerException
    at LookupService.isFirstElement(LookupService.java:5)
    at Dictionary.isFirstElement(Dictionary.java:15)
    at Dictionary.main(Dictionary.java:22)

The exception is triggered in the LookupService class while the origin of it is well earlier (the Dictionary constructor). It makes the overall issue analysis much less obvious.
Is words null? Is words.get(0) null ? Both ? Why the one, the other or maybe both are null ? Is it a coding error in Dictionary (constructor? invoked method?) ? Is it a coding error in LookupService ? (constructor? invoked method?) ?
Finally, we will have to inspect more code to find the error origin and in a more complex class maybe even use a debugger to understand more easily what it happened.
But why a simple thing (a lack of null check) become a complex issue ?
Because we allowed the initial bug/lack identifiable on a specific component leak on lower components.
Imagine that LookupService was not a local service but a remote service or a third party library with few debugging information or imagine that you didn't have 2 layers but 4 or 5 layers of object invocations before that the null be detected ? The problem would be still more complex to analyse.

So the way to favor is :

public Dictionary(List<String> words) {
    this.words = Objects.requireNonNull(words);
    this.lookupService = new LookupService(words);
}

In this way, no headache : we get the exception thrown as soon as this is received :

// exception thrown early : in the constructor 
Dictionary dictionary = new Dictionary(null);

// we never arrive here
boolean isFirstElement = dictionary.isFirstElement("anyThing");
Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at com.Dictionary.(Dictionary.java:15)
    at com.Dictionary.main(Dictionary.java:24)

Note that here I illustrated the issue with a constructor but a method invocation could have the same non null check constraint.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
16

NPE (Null Pointer Exception) is thrown when you access a member of an object which is null at a later point. Objects.requireNonNull() backtracks from where the value was accessed to where it was initialized as null, thus allowing to focus on real source of NPE.

A simplest scenario:

// Global String
String nullString = null;

Calling the null value:

public void useString() {
    nullString.length();  // The source of exception, without using Objects.requireNonNull()
}

Now if we use Objects.requireNonNull() during initialization:

// Global String
String nullString = Objects.requireNonNull(null); // The source of exception which is indeed the actual source of NPE
Mirwise Khan
  • 1,317
  • 17
  • 25
  • 2
    I'll rephrase: it immediately indicates where and when the null value **occurred** rather than when this value was first accessed (with an NPE). – Violet Giraffe Aug 09 '22 at 14:08
2

As a side note, this fail fast before Object#requireNotNull was implemented slightly different before java-9 inside some of the jre classes themselves. Suppose the case :

 Consumer<String> consumer = System.out::println;

In java-8 this compiles as (only the relevant parts)

getstatic Field java/lang/System.out
invokevirtual java/lang/Object.getClass

Basically an operation as : yourReference.getClass - which would fail if yourRefercence is null.

Things have changed in jdk-9 where the same code compiles as

getstatic Field java/lang/System.out
invokestatic java/util/Objects.requireNonNull

Or basically Objects.requireNotNull (yourReference)

Eugene
  • 117,005
  • 15
  • 201
  • 306
1

Apart from the other answers - to me use of requireNonNull could make a code a bit convenient, (and sometimes easy to read)

For example - lets examine the code below,

private int calculateStringLength(String input) {
        return Objects.
                requireNonNull(input, "input cannot be null").
                length();
    }

This code returns length of the string passed to it as argument - however it will throw an NPE if input is null.

As you can see, with use of requireNonNull - there’s no reason to perform null checks manually anymore.

The other useful thing is the "exception message" is my own hand-written (input cannot be null in this case).

AADProgramming
  • 6,077
  • 11
  • 38
  • 58
  • I like this idea in old code, but with the existence of more modern methods, it could make the code "less readable" too, according to [link](https://dzone.com/articles/why-i-never-null-check-parameters). – aderchox Sep 26 '21 at 16:58
1

There is also the added benefit that static analysis tools generally know @NonNull and @Nullable for standard library (which is the same as checking for null explicitly) :

public static <T> @NonNull T requireNonNull(@Nullable T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}
cquezel
  • 3,859
  • 1
  • 30
  • 32
0

The basic usage is checking and throwing NullPointerException immediately.

One better alternative (shortcut) to cater to the same requirement is @NonNull annotation by lombok.

Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
  • 1
    The annotation is not a replacement for the Objects method, they work together. You can't say @ NonNull x=mightBeNull, you would say @ NonNull x=Objects.requireNonNull(mightBeNull, "inconceivable!"); – Bill K Aug 27 '19 at 21:37
  • @BillK sorry, i dont get u – Supun Wijerathne Aug 28 '19 at 14:44
  • I was just saying that the Nonnull annotation works with requireNonNull, it is not an alternative, but they work together quite well. – Bill K Aug 28 '19 at 16:08
  • to implement the fail fast nature, its an alternative right? Yh I agree its not an alternative for the assignment. – Supun Wijerathne Aug 29 '19 at 01:27
  • I guess I'd call requireNonNull() a "conversion" from @ Nullable to @ NonNull. If you don't use the annotations, the method isn't really very interesting (since all it does is throw an NPE just like the code it protects would)--although it does pretty clearly show your intent. – Bill K Aug 29 '19 at 16:26
0

I think it should be used in copy constructors and some other cases like DI whose input parameter is an object, you should check if the parameter is null. In such circumstances, you can use this static method conveniently.

Yu Chai
  • 77
  • 4
0

In the context of compiler extensions that implement Nullability checking (eg: uber/NullAway), Objects.requireNonNull should be used somewhat sparingly for occasions when you have a nullable field that you happen to know is not null at a certain point in your code.

In this way, there are two main usages:

  • Validation

    • already covered by other responses here
    • runtime check with overhead and potential NPE
  • Nullability marking (changing from @Nullable to @Nonnull)

    • minimal use of runtime check in favor of compile-time checking
    • only works when annotations are correct (enforced by the compiler)

Example usage of Nullability marking:

@Nullable
Foo getFoo(boolean getNull) { return getNull ? null : new Foo(); }

// Changes contract from Nullable to Nonnull without compiler error
@Nonnull Foo myFoo = Objects.requireNonNull(getFoo(false));
imoverclocked
  • 178
  • 1
  • 4
0

In addition to all the correct answers:

We use it in reactive streams. Usually the resulting NullpointerExceptions are wrapped into other Exceptions depending on their occurance in the stream. Hence, we can later easily decide how to handle the error.

Just an example: Imagine you have

<T> T parseAndValidate(String payload) throws ParsingException { ... };
<T> T save(T t) throws DBAccessException { ... };

where parseAndValidate wrapps the NullPointerException from requireNonNull in a ParsingException.

Now you can decide, e.g. when to do a retry or not:

...
.map(this::parseAndValidate)
.map(this::save)
.retry(Retry.<T>allBut(ParsingException.class))

Without the check, the NullPointerException will occure in the save method, which will result in endless retries. Even worth, imagine a long living subscription, adding

.onErrorContinue(
    throwable -> throwable.getClass().equals(ParsingException.class),
    parsingExceptionConsumer()
)

Now the RetryExhaustException will kill your subscription.

PeMa
  • 1,559
  • 18
  • 44