Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to notify the programmer of a null argument?

So, I'm working on designing a class wherein if certain arguments to certain methods are null, either the method (or the object as a whole) won't work.

I know that it'll throw a NullPointerException once it receives the null object and attempts to use it, but I want the programmer trying to call the method to understand that the bug is not in my code. I just want to ensure that the resulting exception thrown would be very clear (without the need to look into my source).

I've seen a few examples of what I described, where they throw an IllegalArgumentException when the parameter is null.

Here's the difference, imagine that someObject will somehow be vital to the method:

public void doSomething(SomeClass someObject) {
    if (someObject == null) throw new IllegalArgumentException("someObject is null");
    ...
}

This way, the programmer understands that he or she has broken the contract implied by the javadoc (whether or not it is explicitly stated).

Is that good practice, or even a reasonable thing to do?


Quick Edit/Side-bar:

What would be best to say in the exception message?

Is it better to state what "went wrong":

someObject is null

Or is it better to state that something "went wrong" and generally imply the cause (and ultimately the solution):

someObject cannot be null

Or is there a better alternative?

like image 659
Bhaxy Avatar asked Dec 22 '22 02:12

Bhaxy


2 Answers

Use an IllegalArgumentException instead of allowing the NullPointerException so that you can discover the error as early as possible. You could perform the same check and throw a NullPointerException yourself as well, but that's a matter of semantics.

By throwing the error immediately, it helps you or some other developer catch the mistake before anything else happens. If your method doesn't use the argument immediately (for instance, in a setter), then the problem could appear to be the result of some completely different operation.

If you're not familiar with it, a fantastic book called The Pragmatic Programmer has a tip that I'm trying to emphasize here:

Time 32: Crash Early

The main idea is to fail before anything bad can happen, rather than allow problems to crop up at unexpected times.

This would also be a good place to use an assertion to enforce your precondition. Make sure you document that the argument cannot be null, and make your method look like this:

public void doSomething(SomeClass someObject) {
    assert someObject != null    
    ...
}

If the assertion fails, an error will be thrown. While this could be turned off with compiler options, it's a good practice during development.

like image 129
derekerdmann Avatar answered Jan 06 '23 09:01

derekerdmann


I would say the standard, documented practice is to just use NullPointerException.

  1. It is used explicitly in many @throws Javadocs to document the case when an argument is null and is not allowed to be (Reader.read(CharBuffer), String.contains(CharSequence) and many, many more)
  2. It is recommended in respected coding guidelines (for example, Bloch recommends its use in Effective Java).
  3. The class itself says that it's meant to be thrown explicitly:

    Applications should throw instances of this class to indicate other illegal uses of the null object.

  4. It's what Guava's Preconditions throw for checkNotNull, and they know Java library design.
  5. Using a NullPointerException doesn't prevent you from giving a good error message describing the exception. By doing so you would set such stacktraces apart from the default NPE stacktrace.
If you really want to deviate from the standard, you can use IllegalArgumentException but at that point I'd go one further and create a subclass called NullArgumentException.

Edit

Speaking of Preconditions, you seem on track to be using runtime exceptions effectively for checking values and invariants. I highly recommend you just use Guava's Preconditions library to standardize and simplify this. Your example would just boil down to:

public void doSomething(SomeClass someObject) {
    Preconditions.checkNotNull(someObject, "someObject cannot be null");
    //...
}
like image 40
Mark Peters Avatar answered Jan 06 '23 10:01

Mark Peters