IllegalArgumentException or NullPointerException for a null parameter?

178,119

Solution 1

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 2

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 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.

Share:
178,119
Mike Stone
Author by

Mike Stone

I am a programmer by hobby and by profession. At work, I (currently) mostly work with Java and web technologies, but I enjoy playing with other languages as well. Ruby is my favorite language to use, and so I try to work with it whenever I find the opportunity (and it makes sense). My operating system of choice is Linux (specifically Ubuntu), and my editor of choice is Emacs (I was converted by a combination of my current coworkers and articles from Steve Yegge).

Updated on July 08, 2022

Comments

  • Mike Stone
    Mike Stone almost 2 years

    I have a simple setter method for a property and null is not appropriate for this particular property. I have always been torn in this situation: should I throw an IllegalArgumentException, or a NullPointerException? From the javadocs, both seem appropriate. Is there some kind of an understood standard? Or is this just one of those things that you should do whatever you prefer and both are really correct?

  • matbrgz
    matbrgz almost 15 years
    I have adopted the "throw new IllegalArgumentException("foo == null")" approach. You need to log the variable name anyway (to be certain that you are looking at the right sttatement etc)
  • GaryF
    GaryF almost 15 years
    I don't necessarily agree with the standard (I could actually go either way on the issue), but that IS what the standard usage throughout the JDK is, hence Effective Java making the case for it. I think this is a case of choosing whether or not to follow the standard, or do the thing you feel is right. Unless you have a very good reason (and this certainly may qualify), it's best to follow standard practice.
  • Christopher Smith
    Christopher Smith over 14 years
    Actually, the NullPointerException is supposed to be thrown for "illegal uses of the null reference". Indeed, encapsulation means you should know whether it was caused by the JVM actually dereferencing a bad pointer or the app just rejecting it.
  • Christopher Smith
    Christopher Smith over 14 years
    Sorry, if a programmer looks around "randomly" upon getting any kind of exception... changing the name of an exception isn't going to help much.
  • Christopher Smith
    Christopher Smith over 14 years
    The salient bit is that it is the application that is using null, not the runtime. So there is a fairly large overlap between "when a method has been passed an illegal or inappropriate argument" and "when an application is using null". In theory, if an app passes a null for a field that requires non-null, both criteria are being met.
  • bjornl
    bjornl over 13 years
    Agree with Thorbjorn, do yourself a favor and avoid debugging hell.
  • Gili
    Gili over 13 years
    Food for thought: Maybe the reason that NullPointerException doesn't extend IllegalArgumentException is that the former can occur in cases not involving method arguments.
  • Gili
    Gili over 13 years
    Effective Java 2nd Edition, Item 60: "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. Similarly, if a caller passes an out-of-range value in a parameter representing an index into a sequence, IndexOutOfBoundsException should be thrown rather than IllegalArgumentException."
  • R. Martinho Fernandes
    R. Martinho Fernandes over 13 years
    The JavaDoc for NPE also states the following: "Applications should throw instances of this class to indicate other illegal uses of the null object." This one could be more clear :(
  • mP.
    mP. about 12 years
    The run time wont include a meaningful msg.
  • Jin Kwon
    Jin Kwon almost 12 years
    Actually this comment could derive some other opinion. Let the VM speak in NPE yet the programmers speak in IAE before the VM if they want to.
  • assylias
    assylias over 11 years
    Guava Preconditions.checkNotNull(arg) also throws NPE.
  • Aaron Digulla
    Aaron Digulla over 11 years
    Unfortunately, the validation methods Validate.notNull (commons lang) and Preconditions.checkNotNull (guava) both throw NPE :-(
  • Jim Balter
    Jim Balter about 11 years
    The exception trace shows the point of the exception, so if the difference in the type of the exception causes hell for you or is "the difference that helps you", you are doing something very wrong.
  • Lie Ryan
    Lie Ryan about 11 years
    @Gili: maybe this problem exists in the first place because Java does not support multiple inheritance. If Java supports MI, you'd be able to throw an exception that inherits from both IllegalArgumentException and NullPointerException.
  • Bogdan Calmac
    Bogdan Calmac about 11 years
    This isn't really adding more weight to NullPointerException for illegal null ARGUMENTS. Both the JDK requireNonNull() and Guava checkNotNull() can be called anywhere in the code, with any object. You could call them inside a loop for example. requireNotNull() and checkNotNull() could not possibly assume to be invoked with some method arguments and throw IllegalArgumentException. Note that Guava also has Preconditions.checkArgument() which does throw IllegalArgumentException.
  • PhiLho
    PhiLho almost 11 years
    The message needs not to include the argument, since it would be always null, giving: "null must not be null", not very useful. :-) Otherwise, I agree, you can make a "rich" NPE, with a meaningful message.
  • PhiLho
    PhiLho almost 11 years
    Expensive? I don't think that == null is that expensive... Beside, the null argument can be just stored for latter use, and will throw an exception long after the method call, making the error harder to track. Or you can create an expensive object before using the null argument, and so on. Early detection seems to be a good option.
  • MB.
    MB. over 10 years
    A fair point by Bogdan, though I suspect the typical (and generally intended) use of requireNonNull is for argument checking. If you needed to check that something wasn't null in a loop I'd have thought an assertion would be the typical way.
  • artbristol
    artbristol over 10 years
    Note they removed it from commons-lang3: apache-commons.680414.n4.nabble.com/…
  • michaelok
    michaelok over 10 years
    Although Guava also has Preconditions.checkArgument() throws IllegalArgumentException ...
  • maaartinus
    maaartinus about 10 years
    This would double the overhead for exception creation and wouldn't really help as catching NullPointerException would do nothing. The only thing which could help is IllegalNullPointerArgumentException extends IllegalArgumentException, NullPointerException, but we have no multiple inheritance.
  • SamStephens
    SamStephens about 10 years
    The following answers to this question make persuasive arguments that NullPointerException is the correct exception: stackoverflow.com/a/8160/372926 ; stackoverflow.com/a/8196334/372926 ; and stackoverflow.com/a/6358/372926.
  • flamming_python
    flamming_python almost 10 years
    I have to agree - follow the standard API when in doubt. Not everything in the API is optimal mind you, but still it's maintained and iterated by hundreds of developers, and used by millions of programmers. Now in Java 7 we have another example of the NPE being used in this way; the Objects.requireNonNull(T obj) method - clearly specified for checking that object references are non-null, clearly specified for doing parameter validation in methods/constructors, and clearly specified to throw an NPE if the object is null. End of
  • djechlin
    djechlin almost 10 years
    @ThorbjørnRavnAndersen the stack trace will point you at the exact same spot anyway? certainly doesn't make that much of a difference
  • matbrgz
    matbrgz almost 10 years
    @djechlin it allows you or others to triage the problem early without having to wake a programmer to look at the precise source first.
  • matbrgz
    matbrgz almost 10 years
    The difference between most unchecked exceptions is just the name.
  • matbrgz
    matbrgz almost 10 years
    @JimBalter If nullpointerexceptions are never thrown by your code but only by the JVM when resolving a . or an array index, you can immediately say whether this is bad data caught by your code, or this is unforeseen data resulting in a code malfunction, without having to look at the source first. In a production failure where downtime may be expensive this may allow the initial investigator to react correctly without having to wake up a vendor programmer first.
  • Jim Balter
    Jim Balter almost 10 years
    Fantasies and sophistry. Just below, MB writes "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."
  • Jim Balter
    Jim Balter almost 10 years
    "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." -- It's not at all misleading, quite the contrary. Had you not explicitly checked for a null argument value, you would have gotten an NPE when you used it. The check is just to make the details of the logic error explicit. There is no logical difference between a program that throws an NPE upon derefing null and a program that throws an exception in lieu of derefing null. The exception message should make the cause clear.
  • Jim Balter
    Jim Balter almost 10 years
    "Although Guava also has Preconditions.checkArgument() throws IllegalArgumentException" -- yes, so? That takes a boolean condition; it isn't for use with null arguments.
  • Jim Balter
    Jim Balter almost 10 years
    Also, these points were covered by Christopher Smith , among others, 4 1/2 years ago ... continuing to bring up bogus points is trolling.
  • GaryF
    GaryF almost 10 years
    As the original answerer here, let me say it just doesn't matter that much. It certainly doesn't warrant 6 years of conversation. Pick one, whichever you like, and be consistent. The standard, as I pointed out, is NPE. If you prefer IAE for whatever reasons, go for it. Just be consistent.
  • Arto Bendiken
    Arto Bendiken over 9 years
    @AaronDigulla, from the Guava docs: "We realize there are many valid arguments in favor of throwing IAE on a null argument. In fact, if we had a time machine to go back >15 years, we might even try to push things in that direction. However, we have decided to stick with the JDK and Effective Java preference of NullPointerException. If you're steadfast in your belief that IAE is right, you still have checkArgument(arg != null), just without the convenience of it returning arg, or you can create a local utility to your project." code.google.com/p/guava-libraries/wiki/IdeaGraveyard
  • Richard Zschech
    Richard Zschech about 9 years
    I think the JavaDoc of Object.requireNonNull() adds weight to the argument: "This method is designed primarily for doing parameter validation in methods and constructors"
  • Peter Perháč
    Peter Perháč over 8 years
    it is this quote that brought me here, as i disagree... i guess i won't really find an answer here. i will keep on throwing IAEs rather than NPEs, though I have seen NPE thrown from the java.sql.DriverManager.registerDriver(Driver) method, if Driver is null, NPE is thrown explicitly. I wondered WHY.
  • jpangamarca
    jpangamarca about 8 years
    I second this answer. I guess "Wisdom, not rules" (javapractices.com/topic/TopicAction.do?Id=259) applies here.
  • Alowaniak
    Alowaniak almost 8 years
    I don't see how the contains throws a NPE depending on an element inside the collection. Only reason a NPE is thrown (afaict) is if the collection itself is null (in which case the NPE is thrown because it tries to access it's iterator). This does however raise the question if null input should be checked for or if it should propagate through until it's tried to access.
  • Chris Povirk
    Chris Povirk almost 8 years
    new TreeSet<>().containsAll(Arrays.asList((Object) null)); throws NPE because the List contains null.
  • Alowaniak
    Alowaniak almost 8 years
    Ah indeed, TreeSet#contains throws NPE "if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements". Only looked at AbstractSet which does allow null, my bad. Personally I find it weird it doesn't just return false though, since in that case there can't possibly be a null added.
  • Igor
    Igor over 7 years
    I am using IllegalArgumentException if an argument is given, yet "illegal" in terms of being wrong (as it is unknown to my application - possibly misspelled). I am uncertain about what to throw if no argument is passed - since my application expects at least two arguments...
  • BeeOnRope
    BeeOnRope over 7 years
    Keep in mind that the performance argument in favor of implicit null checks is often invalid. The JIT is able to recognize user null checks and elide the following implied null check, and/or use the same set of optimizations on either type of null check. See this wiki for more info, in particular: User-written null checks are in most cases functionally identical to those inserted by the JVM. Of course, if you are doing something fancier in your null like custom messages, this optimization may not apply.
  • Wouter
    Wouter about 7 years
    NPE: "Applications should throw instances of this class to indicate other illegal uses of the null object." IAE: "Thrown to indicate that a method has been passed an illegal or inappropriate argument."
  • digital_infinity
    digital_infinity over 6 years
    down voting of this answer is misunderstanding of the hardware behind. Certainly the hardware checks (that CPU does) are cheaper that explicit checking. Dereferencing of null is a SegmentationFault (SegV) special case (access to a page not owned by the process) which CPU/OS checks and JRE handles as a special case throwing NullPointerException.
  • Sgene9
    Sgene9 about 6 years
    I believe that more specific exceptions should be wrapped by more general exceptions. NPE is for an expression while IAE is for a method. Since methods contain statements that contain expressions, IAE is more general.
  • Sgene9
    Sgene9 about 6 years
    Regarding the overhead, I have no idea. But since the stacktraces would basically be identical except that the name of the exception changed in the middle, I think there shouldn't be too much overhead for double exceptions. If one is worried about the overhead, he can use "if" statements to return a null or -1 instead of throwing an exception.
  • Pedro Borges
    Pedro Borges almost 6 years
    If you want to be specific, check and throw IAE, if not just let the NPE happen naturally. It is a matter of choice to be explicit (IAE) or implicit (NPE) both are fine, as long as you never throw an NPE explicitly in code :)
  • matoni
    matoni almost 6 years
    IllegalArgumentException is in contradiction with Java's Objects.requireNonNull(T) and Guava's Preconditions.checkNotNull(T) which throws a NullPointerException. However, the right answer is definitelly IllegalArgumentException as explained in Jason Cohen's excelent answer and it's comment section.
  • ACV
    ACV over 5 years
    NullPointerException could be thrown not only by null parameters, but also by null variables inside the method.
  • Mr.Q
    Mr.Q about 5 years
    No, There is just one right answer to this question and that is to use throw IllegalArgument exception when the input to the method is incorrect. Also in dev environment, you can use assertions to check input validity and throw proper exception ;)
  • Solomon Ucko
    Solomon Ucko almost 5 years
    @Mr.Q And I think that NullPointerException should be thrown: it's the convention that the JDK uses, and requires for interfaces, it's more specific (just like IndexOutOfBoundsException, etc.), etc.
  • Yousha Aleayoub
    Yousha Aleayoub over 4 years
    kekekekkek... :D
  • matoni
    matoni over 3 years
    Also from test-case perspective, IAE is more suitable, since NPE can be any line of code with "null.callMethod()", while IAE immediatelly identifies invalid argument scenario.