IllegalArgumentException or NullPointerException for a null parameter? [closed]
Solution 1:
You should be using IllegalArgumentException
(IAE), not NullPointerException
(NPE) for the following reasons:
First, the NPE JavaDoc explicitly lists the cases where NPE is appropriate. Notice that all of them are thrown by the runtime when null
is used inappropriately. In contrast, the IAE JavaDoc couldn't be more clear: "Thrown to indicate that a method has been passed an illegal or inappropriate argument." Yup, that's you!
Second, when you see an NPE in a stack trace, what do you assume? Probably that someone dereferenced a null
. When you see IAE, you assume the caller of the method at the top of the stack passed in an illegal value. Again, the latter assumption is true, the former is misleading.
Third, since IAE is clearly designed for validating parameters, you have to assume it as the default choice of exception, so why would you choose NPE instead? Certainly not for different behavior -- do you really expect calling code to catch NPE's separately from IAE and do something different as a result? Are you trying to communicate a more specific error message? But you can do that in the exception message text anyway, as you should for all other incorrect parameters.
Fourth, all other incorrect parameter data will be IAE, so why not be consistent? Why is it that an illegal null
is so special that it deserves a separate exception from all other types of illegal arguments?
Finally, I accept the argument given by other answers that parts of the Java API use NPE in this manner. However, the Java API is inconsistent with everything from exception types to naming conventions, so I think just blindly copying (your favorite part of) the Java API isn't a good enough argument to trump these other considerations.
Solution 2:
It seems like an IllegalArgumentException
is called for if you don't want null
to be an allowed value, and the NullPointerException
would be thrown if you were trying to use a variable that turns out to be null
.
Solution 3:
The standard is to throw the NullPointerException
. The generally infallible "Effective Java" discusses this briefly in Item 42 (first edition), Item 60 (second edition), or Item 72 (third edition) "Favor the use of standard exceptions":
"Arguably, all erroneous method invocations boil down to an illegal argument or illegal state, but other exceptions are standardly used for certain kinds of illegal arguments and states. If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException."
Solution 4:
I was all in favour of throwing IllegalArgumentException
for null parameters, until today, when I noticed the java.util.Objects.requireNonNull
method in Java 7. With that method, instead of doing:
if (param == null) {
throw new IllegalArgumentException("param cannot be null.");
}
you can do:
Objects.requireNonNull(param);
and it will throw a NullPointerException
if the parameter you pass it is null
.
Given that that method is right bang in the middle of java.util
I take its existence to be a pretty strong indication that throwing NullPointerException
is "the Java way of doing things".
I think I'm decided at any rate.
Note that the arguments about hard debugging are bogus because you can of course provide a message to NullPointerException
saying what was null and why it shouldn't be null. Just like with IllegalArgumentException
.
One added advantage of NullPointerException
is that, in highly performance critical code, you could dispense with an explicit check for null (and a NullPointerException
with a friendly error message), and just rely on the NullPointerException
you'll get automatically when you call a method on the null parameter. Provided you call a method quickly (i.e. fail fast), then you have essentially the same effect, just not quite as user friendly for the developer. Most times it's probably better to check explicitly and throw with a useful message to indicate which parameter was null, but it's nice to have the option of changing that if performance dictates without breaking the published contract of the method/constructor.
Solution 5:
I tend to follow the design of JDK libraries, especially Collections and Concurrency (Joshua Bloch, Doug Lea, those guys know how to design solid APIs). Anyway, many APIs in the JDK pro-actively throws NullPointerException
.
For example, the Javadoc for Map.containsKey
states:
@throws NullPointerException if the key is null and this map does not permit null keys (optional).
It's perfectly valid to throw your own NPE. The convention is to include the parameter name which was null in the message of the exception.
The pattern goes:
public void someMethod(Object mustNotBeNull) {
if (mustNotBeNull == null) {
throw new NullPointerException("mustNotBeNull must not be null");
}
}
Whatever you do, don't allow a bad value to get set and throw an exception later when other code attempts to use it. That makes debugging a nightmare. You should always the follow the "fail-fast" principle.