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?
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?
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.
I would say the standard, documented practice is to just use NullPointerException
.
@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)Applications should throw instances of this class to indicate other illegal uses of the
null
object.
Preconditions
throw for checkNotNull
, and they know Java library design.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.IllegalArgumentException
but at that point I'd go one further and create a subclass called NullArgumentException
.
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");
//...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With