Why Should One Use Objects.Requirenonnull()

Why should one use Objects.requireNonNull()?

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!

What is the purpose of Objects#requireNonNull

A good principle when writing software is to catch errors as early as possible. The quicker you notice, for example, a bad value such as null being passed to a method, the easier it is to find out the cause and fix the problem.

If you pass null to a method that is not supposed to receive null, a NullPointerException will probably happen somewhere, as you already noticed. However, the exception might not happen until a few methods further down, and when it happens somewhere deep down, it will be more difficult to find the exact source of the error.

So, it's better when methods check their arguments up front and throw an exception as soon as they find an invalid value such as null.

edit - About the one-parameter version: even though you won't provide an error message, checking arguments and throwing an exception early will be more useful than letting the null pass down until an exception happens somewhere deeper down. The stack trace will point to the line where you used Objects.requireNonNull(...) and it should be obvious to you as a developer that that means you're not supposed to pass null. When you let a NullPointerException happen implicitly you don't know if the original programmer had the intent that the variable should not be null.

Is Objects.requireNonNull less efficient than the old way?

Let's look at the implementation of requireNonNull in Oracle's JDK:

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

So that's very simple. The JVM (Oracle's, anyway) includes an optimizing two-stage just-in-time compiler to convert bytecode to machine code. It will inline trivial methods like this if it can get better performance that way.

So no, not likely to be slower, not in any meaningful way, not anywhere that would matter.

So my question: is there any evidence of a performance penalty being incurred by using the Objects.requireNonNull methods?

The only evidence that would matter would be performance measurements of your codebase, or of code designed to be highly representative of it. You can test this with any decent performance testing tool, but unless your colleague can point to a real-world example of a performance problem in your codebase related to this method (rather than a synthetic benchmark), I'd tend to assume you and he/she have bigger fish to fry.


As a bit of an aside, I noticed your sample method is a private method. So only code your team is writing calls it directly. In those situations, you might look at whether you have a use case for assertions rather than runtime checks. Assertions have the advantage of not executing in "released" code at all, and thus being faster than either alternative in your question. Obviously there are places you need runtime checks, but those are usually at gatekeeping points, public methods and such. Just FWIW.



Related Topics



Leave a reply



Submit