And ruled that yeah, it was OK for an application to throw an NPE. Back to today: a dev reviewed the pull request from another one, found out it threw an NPE and ruled it was bad practice.
NullPointerException is thrown when program attempts to use an object reference that has the null value. These can be: Invoking a method from a null object. Accessing or modifying a null object's field.
Generally It is recommend that one should not catch NullPointerException and let it be handled by JVM. if you will not do, then chances are there that NullPointerException can occur if no data is there. In reality, your example shows why it is a BAD IDEA to catch NPEs.
In Java, the java. lang. NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.
I would recommend you never throw NullPointerException
by yourself.
The main reason not to do this, as Thorbjørn Ravn Andersen says in a comment below, is that you don't wan't to mix 'real, bad NPEs' with NPEs thrown intentionally.
So, until you're confident that you're able to recognize 'valid' NPE, I'd recommend to use IllegalArgumentException
when you want to tell to your API user that null
is not a valid argument value. Your method's behavior when illegal null-parameter passed should be documented.
Another (more modern imho) option is to use @NotNull
annotation near the argument.
Here is an article about using @NotNull annotation.
As I mentioned earlier, there can also be cases, when throwing NPE will not be confusing either to you or to your teammates: NPE cause should be clear and recognizable.
For instance, if you use some library with preconditions module, like Guava
, then I find using checkNotNull()
-like methods is a preferable way to deal with illegally-passed nulls.
checkNotNull(arg, msg)
throws NPE, but from the stacktrace it's quite clear, that it was produced by Preconditions.checkNotNull()
and thus it's not an unknown bug but rather expected behavior.
I see no problem with throwing a NPE as early as possible before the JVM does it for you - in particular for null arguments. There seems to be some debate about this, but there are many examples in the Java SE libraries that does exactly this. I cannot see why NPE should be holy in the aspect that you are not able to throw it yourself.
However, I digress. This question is about something different. You are talking about a post-condition stating that the return value mustn't be null. Surely null in this case would mean you have a bug inside the very method?
How would you even document this? "This method throws a NullPointerException if the return value unexpectedly is null"? Without explaining how this could happen? No, I would use an assertion here. Exceptions should be used for errors that can conceivably happen - not to cover things that can happen if there's something wrong inside the method, because that does not help anybody.
Given that NullPointerException
is the idiomatic way to communicate an unexpected null value in Java, I would recommend you throw a standard NullPointerException
and not a homegrown one. Also keep in mind that the principle of least surprise would suggest that you don't invent your own exception type for a case where a system exception type exists.
Assertions are good for debugging but not good if you have to handle certain conditions so that's not really a good way to handle the error condition.
The problem with NullPointerException
is, that it occures when you forget to check if something is null or give the wrong argument that is null, and shouldn't.
From my experience, Java programmers learn very quickly that this exception is caused by the bug in code, so throwing it manually will be extremally confusing for most of them. IllegalArgumentException
is better idea when you pass unacceptable argument (such as null, where something must not be null).
It triggers also another heuristic. NPE = someone made error in code here, IllegalArgumentException
= the object given to the method is invalid.
On the other hand, the javadoc tells:
Applications should throw instances of this class to indicate
other illegal uses of thenull
object.
So throwing NPE would be legal, however it's not the common practice, so I would recommend IllegalArgumentException
.
There certainly isn't a universal law against throwing NullPointerException, but it's tough to answer if you actually should in such an abstracted example. What you don't want to do is put people up the chain in the position of trying to catch NullPointerException. Code like this (real example, I swear):
catch (NullPointerException npe) {
if (npe.getMessage().equals("Null return value from getProdByCode") {
drawToUser("Unable to find a product for the product type code you entered");
}
}
Is a surefire indicator you're doing something wrong. So if the null return value is an indicator of some system state that you're actually able to communicate, use an exception that communicates that state. There aren't many cases I can think of where it makes sense to null check a reference just to chuck a nullpointer. Usually the very next line of code would have chucked the nullpointer (or something more informative) anyway!
http://pmd.sourceforge.net/pmd-5.0.1/rules/java/strictexception.html
"Avoid throwing NullPointerExceptions. These are confusing because most people will assume that the virtual machine threw it. Consider using an IllegalArgumentException instead; this will be clearly seen as a programmer-initiated exception."
I would consider that usage of NullPointerException ok, if you remember the description. That is what the person investigating has work with (line numbers may shift). Also remember to document that your methods throw null pointer exceptions in special cases.
If you check your method parameters right in the beginning, a throw new IllegalArgumentException("foo==null")
is acceptable to me too.
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