views:

451

answers:

12

Hi,

When there is a post-condition, that return value of a method must not be null, what can be done ?

I could do

assert returnValue != null : "Not acceptable null value";

but assertions could be turned off !

So is it okay to do

if(returnValue==null)
      {
           throw new NullPointerException("return value is null at method AAA");
      }

?

Or is it better to use a user-defined exception (like NullReturnValueException ) for such a condition ?

+14  A: 

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.

Timo Geusch
A: 

A book I have called O'Reilly's Java in A Nutshell which is written by an expert lists this definition for NullPointerException:

Signals an attempt to access a field or invoke a method of a null object.

Since returning null isn't either of those things, I think it'd be more appropriate to write your own exception.

Rafe Kettler
Erm, simply because some unnamed book uses this definition does not make it a universally accepted one - especially if it contradicts the JavaDoc of that exception.
meriton
From the java documentation, "Thrown when a program tries to access a field or method of an object or an element of an array when there is no instance or array to use, that is if the object or array points to {@code null}. It also occurs in some other, less obvious circumstances, like a {@code throw e} statement where the Throwable reference is {@code null}."
Rafe Kettler
Where in the Java documentation ...? The JavaDoc to that exception ends with "Applications should throw instances of this class to indicate other illegal uses of the null object."
meriton
What JavaDoc are you looking at? https://www.docjar.com/docs/api/java/lang/NullPointerException.html takes its info from JavaDoc. You're misinterpreting what you get from the website you call JavaDoc, which is actually more along the lines of a wiki. None of those cases have anything to do with returning a null value.
Rafe Kettler
Interesting that the Apache Harmony project would choose to provide a different javadoc than the Sun implementation of the JDK, to which I linked (that the link is no longer hosted at sun is really Oracle's fault). Note that according to their website, Apache Harmony is not a certified implementation of Java. In fact, they don't claim to be fully compatible with it.
meriton
A: 

The JavaDoc for NullPointerException states:

Thrown when an application attempts to use null in a case where an object is required. These include:

* Calling the instance method of a null object.
* Accessing or modifying the field of a null object.
* Taking the length of null as if it were an array.
* Accessing or modifying the slots of null as if it were an array.
* Throwing null as if it were a Throwable value. 

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

I consider violating the post-condition an illegal action. However, I think what exception you use doesn't matter much, because we are talking about a code path that should be (and hopefully is) unreachable, and hence you will not have error handling specific to that exception, and hence the only effect of that name is a different wording of some entry in a log file nobody is ever likely to see.

If in contrast you think the post condition is likely to be violated it might be a good idea to include more debugging information, such as the arguments the method was invoked with.

meriton
+5  A: 

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!

Affe
This particular example would hopefully be caused by an empty ProdCode input field?
Thorbjørn Ravn Andersen
If only, that would at least sort of make sense. This is how a contract dev I worked with was handling the result of a search based on user input.
Affe
+2  A: 

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.

Thorbjørn Ravn Andersen
+12  A: 

I would recommend you never throw NullPointerException by yourself.

If you want to tell to your API user that null is not a valid argument value then throw IllegalArgumentException, it exists just for the case.

Another (more modern imho) option is to use @NotNull annotation near the argument.

Here is an article about using @NotNull annotation.

Roman
Actually NullPointerException is a **great** way to tell, that an argument should not be null. See Effective Java: *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.*
Willi
@Willi Schönborn: everybody makes mistakes sometimes, Josh Bloch is not an exception here. Personally, I wouldn't throw either `NullPointerException` or `IllegalArgumentException`. If `null` is illegal param value, then I would write it in javadoc for the method, I'd use `@NotNull` annotation and let the caller solve all further problems if he still passes `null`.
Roman
Take a look at the javadoc: *Applications should throw instances of this class to indicate other illegal uses of the null object.* That's pretty clear to me. Throwing NPEs is legal and valid and should be done for every non-null parameter when null is passed in. Period.
Willi
@Willi Schönborn: I'd like to stop this discussion. Javadoc cannot be a strict reference, it's just a documentation on classes. Moreover, things changes, NPE is in java from its first version, nobody was sure then what is convenient and what is not convenient.
Roman
@willi,keeping npe's to be only thrown by the runtime not your own code, makes it easy to determine how serious a npe is.
Thorbjørn Ravn Andersen
A: 

IMO you should never manually throw a NullPointerException. The calling routine wouldn't know if the real or manual NullPointerException without checking the description. In this case it looks like you would want to roll your own exception that matches the problem closer, so that the calling method can correctly recover frm this exception. Maybe a PostConditionException would be generic enough for many circumstances.

Jerod Houghtelling
totally agree, it should be thrown by JVM. We should catch it and handle.
Truong Ha
I totally disagree. A null value in à context where it is not expected should yield a NPE. THE advantage of throwing it yourself is that you can add à usefull message in it.
extraneon
A: 

Throw that exception is not a good practice in some case and I wonder why when you already catch it with the if statement?

if(returnValue==null)

Truong Ha
+1  A: 

If you describe a method contract where the return value can not be null, then you had better make sure you don't return null. But this isn't a NullPointerException at all. If the value you have to return is null then clearly the caller has either given you bad arguments (IllegalArgumentException), you are not in a valid state (IllegalStateException), or some other much more meaningful exceptional condition has occurred other than NullPointerException (which usually indicates a programming error).

Tim Bender
A: 

In the Java-verse null is always a valid value when expecting an object. You're better off avoiding such impossible post conditions. If you really can't abide a null then you'll have to rework your method so you can return a primitive.

CurtainDog
+1  A: 

It's often a really good idea to throw NPE before the logic gets so deep that the calling programmer will have a hard time figuring out what was null. addListener() methods are a good example.

EJP
+2  A: 

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.

waxwing