I am starting to add tests to a large java code base. I often see the following in the session beans I am testing:
public OrderDTO getOrderDTO(Long id) {
Order o = (Order)entityManager.find(Order.class, id);
OrderDTO dto = new OrderDTO(o.getId(), o.getCurrency());
return dto;
}
Its quit easy to write a unit test to break this code (send in a null or a non existing id). When I did that half the developers of the team said:
We are not error checking everything. If you parameter is rubbish you will know fast!
The other half said:
We must add ifs to the id and then to the o and if any of them are null the null is what we return.
Isn't the point of unit testing to find exactly thees kind of issues?
(Yes, I am asking for an opinion!)
Yes, switching from Long to long will remove one if.
While this is somewhat opinion based, few people would say it's correct to return null if given null as a parameter. If I were to add anything, it would be at most a IllegalArgumentException (or even NPE) when null is passed in.
A test could be created to check that the method fails in a consistent fashion, but it would really be testing the behaviour of the JPA provider and not your code.
Returning nulls should be avoided, they are the source of all evil.
You could use the Null Object Pattern.
Or throw an exception, illegalargument or entitynotexsits spring to mind.
If you must return null, at least wrap it in an optional or use guava.
As always, it depends :)
If you are writing library code (code that is shared and used elsewhere or even by others), then you should really aim for handling all thinkable input values in a consistent way. Using well documented exceptions instead of returning null is certainly preferable for library code.
On the other hand there is local code.
I can see the method is public, but that does not eliminate the possibility that it's only used in one isolated portion of the code base.
In that case, you don't work with assumptions about parameters and what the caller expects in return. You work with defined calls. You control what is sent in and how the caller handles the return value. So it's OK not to null-check, if you know the caller never sends null. And it can be OK to return null as well if that simplifies your overall program structure.
ps: what bothers me most in that method is the unhandled NPE if entityManager.find(..) fails :)
Related
I used to use lots of #NotNull/#Nullable annotations to enable IDE to help me find out potential NPE at compile time. However, my new team doesn't allow any use of #NotNull/#Nullable annotations, and nor are custom annotations like those allowed. As a result, I become much more likely to write bugs caused by NPE than before.
I have tried several solutions:
Use Optional<T> in java 8. However, this is not doing well for every case. It's usually not recommended to use Optional<T> as the type of fields or arguments. It's also very frustrating that Optional<T> instance itself could be null. Also, it's difficult to operate control flows inside lambda expressions when calling ifPresent(obj->...)(it's easier in Java 9). And using too many Optional<T>s makes the code a little verbose.(UPDATE: Unfortunately, Optional<T> is also banned from using now)
Make IDE treat every unannotated instance as #Nullable. This solution does help me find out some potential bugs, however, IDE would suggest me to check almost every method invocation, which is really annoying, since many methods are designed intentionally not returning null.
Check every method invocations. This is a viable solution, however it has a severe influence that the possibility of being null would be passed everywhere through method invocations. Under such circumstances, every argument of a method is possible to be null, and when an argument is checked for nullity, the method would usually return a null continuously. Finally, every method is "infected" with the possibility of receiving null arguments and returning null.
Call Objects.requireNonNull() to prevent the problem aforementioned. It slightly reduces the pain of checking null everywhere. However, it provides no guarantee that the caller won't pass a null to the cases when null is not allowed. And once null is passed, the runtime NPE thrown is much more likely to ruin your application.
Switch to kotlin. Of course, it's not allowed:)
Is there other suggestions about detecting NPE at compile time (and save my job)? I think a solution to this problem could be widely used, not only helping myself, since not all teams allow usage of #NotNull/#Nullable annotations and Optional<T>s.
Not a definitive answer but a few way to explore:
Tools like findBug, PMD , Coverity ... are quite good at this exercice.
Check the reason why you cannot use the annotation in your team. Maybe you can make your team change its mind? (There might be a good reason too.)
Eclipse IDE is reasonnably good at this exercice. Did you try the options in 'Windows > Preferences > Java > Compiler > Errors/Warnings > Null analysis'?
Unit testing. Cover the 'should-not-happen' situation in a few test cases. Code coverage tools (like JaCoCo) might be helpfull as wel.
Defensive programming (plain 'if' statement, assertions ...)
A mix of the previous items
Hope this helps.
You did not say what IDE you are using but Eclipse and Intellij support external annotations. With them, you can still annotate your code locally and have the IDE provide null analysis.
Intellij Documentation
Eclipse Documentation
You can probably find a way to use Optional<T> that suits your cases.
Let's say you have to write a method U doStuff(T param), and that param is given to your code by some library from other person and it may be null.
Inside the body of the method doStuffyou can do
return Optional.ofNullable(param)
.map(notNullParam -> doThing(notNullParam))
.orElse(null);
This way, you are sure that your Optionalitself is not null, people can still use your API with parameters that are null, and you return null when it makes sense for them.
I recommend checking out SonarLint which is a very nice tool to detect all kind of bugs and errors including NPE.
What you should do - is come up with a good API design and specify which of the layers are allowed to return null and which not.
In general, you should always try to return something else rather than null - empty collection, an object representing not-found.
So you should check for nulls manually where the return could make sense to be null. Otherwise, just convene to not return null and just don't check.
You can also introduce some utility methods to check for null/empty collections:
Check.isEmpty() would return true if collection is null or is not null but is empty and so on...
You could also use the null-object pattern
I can relate your problem to my use cases as well. In those cases feel free to suggest code coverage tools.
JaCoCo is very handy. If you use IntelliJ, inbuilt Jacoco/IJ's code coverage clearly gives you the violations and possible NPE
Unit tests to support your domain wise non-nullable object scenarios
After all, NPE is still either design based/programmer based fault. Keep your code well tested and proper checks to avoid NPE and throw custom exceptions or IllegalArgumentException if your service expects a valid value.
After a few reading and questions like this one I was wondering if there was a point in using #NonNull Android Support Annotation.
I can see a very small warning from Android Studio if I attempt to call a method with a null parameter that is annotated as #NonNull. Just a warning??
What about Unit Testing ? Should I test the method with a null paramter? If I do ... I will get a NullPointerException and my test will fail.
Let's say we are two developers. One working on the API and one testing the API in all kind of manners.
As the second developer, it's my responsibility to test everything so that the API is bullet-proof. That's the whole point of Unit Testing, right ?
So then ... what's the point of the first developer using #NonNull ?
If someone else were to use this API with a null parameter ... then the API would throw a NPE. He then would think : "Urg, that API sucks... NPE !" and he would be right. That naughty dev for not checking if the parameter he sent is null or not should be faced with an IllegalArgumentException because it's his fault not that of the API's!
Am I wrong ?
I thought these annotations would enforce the compiler to show errors like attempting to call methodName(#NonNull Object object) with null parameter.
Update 1
Alright thank you all for your comments. I'd like to summ up if possible regarding the "issue" I am facing here. In an abstract way.
I write some code (an API, a Library, a Class, whatever) with private internal code wrapped by public methods that provides features.
Assume these public methods will be used by anyone else (including me).
Some of them take arguments that must never be null or else all hell breaks loose.
Reading your comments, I am facing the following options :
Keep on using contracts / annotations (#NonNull) supported by Java Documentation stipulating parameter must not be null. Don't check for null parameters (or else IDE will warn me) and, somehow, pray that I will never receive a null parameter ;
Same as above, but enforce a null check (even though IDE will warn that condition will always be false) and throw IllegalArgumentException instead of causing an NPE in case I receive a null parameter ;
Stop using contracts / annotations, use Java Doc to warn others dev and add manual check for all parameters.
Finally, for unit testing ... I know I can not have bullet-proof code, but I like to "monkey-test" my code as much as possible to prevent unexpected behavior from my code as well to validate the process (which is at the base of Unit Testing, I believe)-
Its main purpose is informational to your coworkers. One person is never the sole programmer of a large project. Using NotNull tells other programmers that the contract of the function means you can never send a null to it, so they don't do it. Otherwise I may make a logical assumption that calling setFoo(null) will clear Foo, whereas the API can't handle not having a Foo.
Your #2 approach in my opinion is the correct way to do it for an API / Library. Use the annotation for static analysis to prevent compile-time attempts to call the method with null, and use a null check at runtime to give a useful exception (and to fail fast / protect from unexpected things from happening in your code) if a null object gets passed in. Use a //noinspection ConstantConditions directive before the null check to tell the IDE to suppress the warning (since you are checking null for a valid reason).
A random NPE indicates that the library/api author has possibly missed something and has a bug that isn't being handled in their code.
An IllegalArgumentException (or NPE with a description of the problem - which exception to use in this instance is an opinion-based argument) indicates that the caller has made a mistake in the way they called the method.
Ultimately though, whether to test for null after you've already annotated with #NonNull is going to be opinion-based and situation-dependent.
It might be too late to comment, but better later than never :)
There is a Traute javac plugin which inserts null-checks into generated bytecode based on method parameter's annotations.
Here is a sample Android project which illustrates that.
When I code, I often ask myself the same question :
Do I have to verify all arguments are not null ? So, in each method, I will have something like that :
if (arg1 == null)
{
throw FooException("...");
}
if (arg2 == null)
{
throw FooException("...");
}
If not, in which case is preferable ?
What's the best practices ?
As always, it depends.
If you're writing an API to be used by other teams / organizations, such defensive programming with precondition checks on public functions can really help your users; when using an external library, a meaningful error message like 'argument passed to foo() should not be null' is way better than NullPointerException thrown from some inner class.
Outside of API, though, I think such checks clutter the code too much. Thrown NullPointerExceptions are usually pretty easy to trace with debugger anyway. In languages that support them, you can consider using assertions - their syntax is usually less cumbersome, and you can turn them off on production so the checks won't degrade performance.
Unfortunetly, yes. you should check all arguments. Now ideally, if you code with good design practices one function should not have more than 4 or 5 arguments, at the most.
Having said that, one should always check for null values in function entry and throw appropriate exception or IllegalArgumentException (my fav).
Furhter, one should never pass NULL to a function and should never return a NULL. Sounds simple but it will save lots of code and bugs. Have a look at the NULL Design Pattern too.
Depends, if you want different exceptions i guess you would have to do that for all occasions where you might get a null value. Another way would be to user DATATYP.TryParse(). Look that up.
Hope it helps.
Since you're throwing an exception anyway, not verifying them would probably just lead to a nullpointerexception or something similar. I'm not entirely sure what the best practices are myself.
You should ideally always verify any arguments before you perform any action that might modify any state or data associated with said arguments. It's better to fail early and in a manageable way (by throwing a exception) than to end up with an inconsistent state / data which then also has to be resolved.
Your methods are expecting certain data to be there, there are some cases when it should be safe to assume that it is actually there (say inside a private method, which is called from other methods which validate input). However in general I would recommend validating arguments whenever they are:
Supplied by a user.
Supplied as part of an API.
Passed between modules of a system .
It's might be worth taking a look at this previous StackOverflow question.
I feel it's mostly down to common sense, and a little down to personal preference.
As others have mentioned, if it's a public API then you want to provide clear error messages wherever possible, so it's best to check parameters before they are used and throw exceptions with messages as per your example.
If it's internal code then there are two other options to think about: use assertions, or don't bother with the validation and rely on debugging. As a rule of thumb, I'll put assertions in if it's code that I expect other developers will be calling or if the condition is subtle enough that debugging it might be a pain. Otherwise, I'll just allow it to fail.
Sometimes you can avoid the issue by using the Null Object pattern. If it's a public API I'd still be inclined to include the checks though.
I'm wondering about the cost of using a try/exception to handle nulls compared to using an if statement to check for nulls first.
To provide more information. There's a > 50% chance of getting nulls, because in this app. it is common to have a null if no data has been entered... so to attempt a calculation using a null is commonplace.
This being said, would it improve performance if I use an if statement to check for null first before calculation and just not attempt the calculation in the first place, or is less expensive to just let the exception be thrown and handle it?
thanks for any suggestions :-)
Thanks for great thought provoking feedback! Here's a PSEUDOcode example to clarify the original question:
BigDecimal value1 = null //assume value1 came from DB as null
BigDecimal divisor = new BigDecimal("2.0");
try{
if(value1 != null){ //does this enhance performance?... >50% chance that value1 WILL be null
value1.divide(divisor);
}
}
catch (Exception e){
//process, log etc. the exception
//do this EVERYTIME I get null... or use an if statement
//to capture other exceptions.
}
I'd recommend checking for null and not doing the calculation rather than throwing an exception.
An exception should be "exceptional" and rare, not a way to manage flow of control.
I'd also suggest that you establish a contract with your clients regarding input parameters. If nulls are allowed spell it out; if they're not, make it clear what should be passed, default values, and what you promise to return if a null value is passed.
If passing null argument is an exceptional case, then I'd throw a NullPointerException.
public Result calculate(Input input) {
if (input == null) throw new NullPointerException("input");
// ...
}
If passing null is an allowed case, then I'd skip the calculation and eventually return null. But that makes in my opinion less sense. Passing null in first instance would seem a bug in the calling code.
Whatever way you choose, it should be properly documented in the Javadoc to avoid surprises for the API user.
Try and catch are close to "free" but throws can be very expensive. Typically VM creators do not optimize exception paths since, well, they are exceptional (supposed to be rare).
NullPointerException indicates a programmer mistake (RuntimeException) and should not be caught. Instead of catching the NullPointerException you should fix your code to cause the exception not to be thrown in the first place.
Worse yet, if you catch the NullPointerException and a different part of the calculation code throws NullPointerException than the one you expect to throw it you have now masked a bug.
To fully answer your question, I would implement it one way, profile it, and then implement it the other way and profile it... then I would only use the one with the if statement that avoids throwing the NullPointerException regardless of which is faster simply because of the point above.
If there's a >50% chance of getting a null, then it's hardly an exception?
Personally, I'd say that if you expect something to happen, you should code for it appropriately - in this case, checking for null and doing whatever is appropriate. I've always understood throwing an exception to not be exceedingly cheap, but couldn't say for certain.
I agree with most of the other responses that you should prefer the null check to the try-catch. And I've upvoted some of them.
But you should try to avoid the need as much as possible.
There's a > 50% chance of getting nulls, because in this app. it is common to have a null if no data has been entered... so to attempt a calculation using a null is commonplace.
That's what you should really be fixing.
Come up with sensible default values that ensure the computation works or avoid calling a computation without supplying the needed input data.
For many of the standard data types and computations involving them there are sensible default values. Default numbers to 0 or 1 depending on their meaning, default strings and collections to empty, and many computations just work. For more complex objects of your own making, consider the Null Object pattern.
If you have any case where a result or input can't be handled by you program then that should be an error. You should know what you program can handle and allow only that. In regards to possible future cases where a result could be handled but isn't yet I would still suggest considering it an error until you actually need that result. If in doubt, you don't know, the program doesn't know, it can't be handled, you haven't equipped your program to handle it so it's an error. The program can't do anything more but to stop.
For user input it is a very bad idea to rely on your program to eventually crash. You don't know when or even if it will crash. It might just end up doing the wrong thing or do ten things then crash that it shouldn't have done and wouldn't have done if input had been validated.
In terms of guarding against your own mistakes that is more of a mixed bag. You'll want to focus a lot more on making sure things work by testing, eliminating unknowns, proof reading, making sure you know exactly how your program works, etc. Still you'll occasionally have cases where internal processing might produce undesirable results.
When it turns out a result isn't an error for a given case you do not handle the exception, you handle null, not an exception. In that case the result is not an error. So you handle the result and not the error. It could not be simpler. If you're catching an exception and then doing something that can be done with an if such as:
try
extra = i_need_it(extra_id)
show('extra', extra)
catch
show('add_extra')
Then that is not right. You have a perfectly acceptable course of action if you don't have the extra thing.
This is much better and it keeps your intention clear without the extra verbosity:
Something extra = i_want_it(extra_id)
if extra ==== null
show('add_extra')
else
show('extra', extra)
Notice here you need nothing special to avoid catching an exception from another layer. How I put try catch above is a bad practice. You should only be wrapping the thing that throws an exception:
Something extra
try
extra = i_need_it(extra_id)
if extra === null
show('add_extra')
else
show('extra', extra)
When you thing about it like that then it is just converting null to exception and then back again. This is Yo-Yo coding.
You should start with:
Object i_need_it(int id) throws
Until you are actually able to implement handling for null. If you're able to implement handling for the exception you can implement the handling for the null.
When it turns out that something isn't always needed either add this method or change i_need_it to it (if null is always handled):
Object|null i_want_it(int id)
An alternative is to check is it exists first:
bool does_it_exist(int id)
The reason this isn't done so often is because it usually comes out like this:
if(does_it_exist(id))
Something i_need = i_need_it(id)
This tends to be more prone to concurrency problems, can require more calls that might be unreliable (IO over network) and can be inefficient (two RTTs rather than one). Other calls are often merged like this such as update if exists, insert if unique, update if exists or insert, etc that then return what would normally be the result of instead initially checking. Some of these have conflicts over payload size efficiency and RTT efficiency which can also vary based on a number of factors.
It is cheaper however when you need alternating behaviour based on if something exists or not but you don't need to work on it. If you also don't need to worry about the above concerns it's a bit clearer.
You may even want:
void it_must_exist(int id) throws
This is again useful because if you need only ensure something exists it's often cheaper than getting it. However it's rare you'll need this as in most cases you'll want to know if something exists so to directly work on it.
A way to conceive it is that you wouldn't make 'does_it_exist' throw an exception when it can simply return a boolean explicitly up the call stack, 'i_want_it' is a combined 'has' and 'get' in effect.
While having two separate methods more clearly separates method signatures, sometimes you may need to pass down from something else and the simplest way for that if you don't mine a bit of ambiguity is:
Object|null get(int id, bool require) throws
This is better as you're handing the contract down the call chain rather than building on a house of sand based on action at a distance. There are ways to pass down your contract more explicitly but it tends to be convoluted YAGNI (IE, pass down a method caller).
You should throw exceptions early and you can want to be safe rather than sorry so false positives are fine. Once you discover it's a false positive though then you fix it at the source.
It should be extremely rare that you're handling exceptions at all. The sheer majority should hit the top, then invoke a logging and output handler. The rest you fix appropriately by passing back the result directly and handling it. When you have one false positive out of many uses, only this that use. Don't just remove the check in the root and break the many other cases where it's still an error.
Java is an unfortunate language because I you can't have a way of saying don't pass null or this variable must be non-null.
When such a feature is lacking, It's often best to check for nulls at their sources, things such as IO rather than for every time something is passed to one of your methods. Otherwise that's an absurd amount of null checking.
You can apply this pattern to create functions to replace your ifs for parameter checking if you really need that. You would replace id with the object itself such as:
Object i_want(Object it) throws
if(it === null)
throw
return it;
Then:
void give_me(Object it)
this.it = Lib<Object>::i_want(it)
A shame there's no passthru type.
Or:
void i_get_it(Getter<Object> g)
this.it = Lib<Object>::i_want(g.gimme())
You might have a specific Getter rather than with generic.
Or:
void i_need_it(Result<Object> r)
this.it = r.require()
If you only do it on the boundary instead (when you call things out side of your control where non-null result can't be guaranteed), while it is preferred to do it there or for any usage of a method documented as returning null and only there as that's where it's really only needed, that does mean that when you do get a null where it doesn't belong (mistakes happen) you're not going to have an easy time finding out where it came from. It can get passed around a lot from IO and not produce a null pointer exception until something tries to operate on it. Such nulls can be passed around the system for days or even months as a ticking time bomb waiting to go off.
I wouldn't do it myself but I wouldn't blame people in some cases for implementing the defensive programming approach above which might be required due to Java's broken type system which is loose by default and can't be restricted. In robustly typed languages, null isn't permitted unless you explicitly say it is.
Please be advised that although I call it broken, I have been typically using significantly looser languages heavily for decades to build large, complex and critical systems without having to litter the codebase with superfluous checks. Discipline and competence are what determine quality.
A false positive is when a result or a condition occurs that you assume is a result that can't be handled by all callers but it turns out that at least one caller can handle it appropriately. In that case you don't handle the exception but instead give the caller the result. There are very few exceptions to this.
Java 8 has Optional but it doesn't really look helpful. It's a horrific case of the inner platform effect trying to implement new syntax as classes and ending up having to add half of the existing Java syntax along with it making it very clunky. As usual modern Java OOP, solves every problem of people wanting less fudge by adding more fudge and over complicating things. If you really want chaining like that you might want to try something such as kotlin which implements that syntax directly.
A modern language will mean you don't have to worry about most of this and just have:
void i_need_it(Object it)
this.it = it
void i_want_it(Object? it)
this.it = it
A modern language might even return the original object for a method without a return (replace void with self as the standard and auto-return) so people can have their fancy chaining or whatever else is fashionable these days in programming.
You can't have a factory with a base class that gives you a Null or NotNull either because you'll still have to pass the base class and that'll be a type violation when you say you want NotNull.
You might want to play around with aspects, static analysis, etc although that's a bit of a rabbit hole. All documentation should indicate if null can be returned (although if indirectly the it can potentially be left out).
You can make a class such as MightHave to wrap your result where you can put on methods like get, require and has if you don't like statics but want to eat an if although it's also in the realm of mildly convoluted and messing with all of your method signatures everywhere boxing everything all over the place, an ugly solution. It's only really handy as an alternative to those rare exception handling cases where exceptions do seem useful due to the complexity of the call graph and the number of unknowns present across layers.
One exceptionally rare case is when your source knows what exception to throw but not if it needs to be thrown but it's hard to pass down (although coupling two layers at a distance where anything can happen in between needs to be approached with caution). Some people might also want this because it can easily give a trace of both where the missing item came from and where it was required which is something using checks might not give (they're likely to fail close to the source but not guaranteed). Caution should be taken as those kinds of problems might be more indicative of poor flow control or excessive complexity than an issue with justified polymorphism, meta/dynamic coding and the like.
Caution should be taken with things such as defaults or the Null Object pattern. Both can end up hiding errors and becoming best guesses or a cure worse than the disease. Things such a NullObject pattern and Optional can often be used to simply turn off or rather bi-pass the inbuilt error handling in your interpreter.
Defaults aren't always bad but can fall into the realm of guessing. Hiding errors from the user end up setting them up to fail. Defaults (and sanitisation) always need to be thought out carefully.
Things such as NullObject pattern and Optional can be overused to effectively turn off null pointer checking. It simply makes the assumption that null is never an error which ends up with programs doing somethings, not others but you know not what. In some cases this might have hilarious results such as if the user's credit card is null. Make sure if you're using such things you're not using them to the effect of simply wrapping all of your code in a try catch that ignores a null pointer exception. This is very common because people tend to fix errors where the exception was thrown. In reality the real error tends to be further away. You end up with one piece of faulty IO handling that erroneously returns null and that null gets passed all around the program. Instead of fixing that one source of null, people will instead try to fix it in all the places it reaches where it causes an error.
NullObject pattern or MagicNoop patterns have their place but are not for common use. You shouldn't use them until it becomes immediately apparent they are be useful in a justified manner that isn't going to cause more problems than it solves. Sometimes a noop is effectively an error.
After posting this question and reading that one I realized that it is very important to know if a method is supposed to return null, or if this is considered an error condition and an exceptions should be thrown. There also is a nice discussion when to return ‘null’ or throw exception .
I'm writing a method and I already know if I want to return null or throw an exception, what is the best way to express my decision, in other words, to document my contract?
Some ways I can think of:
Write it down in the specs / the documentation (will anyone read it?)
Make it part of the method name (as I suggested here)
assume that every method that throws an exception will not return null, and every one that does 'not' throw might return null.
I'm mainly talking about java, but it might apply to other languages, too: Why is there a formal way to express if exceptions will be thrown (the throws keywords) but no formal way to express if null might be returned?
Why isn't there something like that:
public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
return null; // this would lead to a compiler error!
}
Summary and Conclusion
There are many ways to express the contract:
If your IDE supports it (as IntelliJ), it's best to use an annotation like #NotNull because it is visible to the programmer and can be used for automated compile time checking. There's a plugin for Eclipse to add support for these, but it didn't work for me.
If these are not an option, use custom Types like Option<T> or NotNull<T>, which add clarity and at least runtime checking.
In any way, documenting the contract in the JavaDoc never hurts and sometimes even helps.
Using method names to document the nullability of the return value was not proposed by anyone but me, and though it might be very verbose und not always useful, I still believe sometimes it has its advantages, too.
A very good follow up question. I consider null a truly special value, and if a method may return null it must clearly document in the Javadoc when it does (#return some value ..., or null if ...). When coding I'm defensive, and assume a method may return null unless I'm convinced it can't (e.g., because the Javadoc said so.)
People realized that this is an issue, and a proposed solution is to use annotations to state the intention in a way it can be checked automatically. See JSR 305: Annotations for Software Defect Detection, JSR 308: Annotations on Java Types and JetBrain's Nullable How-To.
Your example might look like this, and refused by the IDE, the compiler or other code analysis tools.
#NotNull
public Object methodWhichCannotReturnNull(int i) throws Exception
{
return null; // this would lead to a compiler error!
}
You can use the Option type, which is very much like a list that has zero or one element. A return type of Option<Object> indicates that the method may return an Object, or it may return a special value of type None. This type is a replacement for the use of null with better type checks.
Example:
public Option<Integer> parseInt(String s) {
try {
return Option.some(Integer.parseInt(s));
}
catch (Exception e) {
return Option.none();
}
}
If you use this consistently, you can turn on IDE null-warnings, or just use grep for null which should not appear in your code at all if you use Option.none() everywhere you would normaly use a null literal.
Option comes standard with Scala, and it is called Maybe in Haskell. The link above is to a library called Functional Java that includes it. That version implements the Iterable interface, and has monadic methods that let you compose things nicely. For example, to provide a default value of 0 in case of None:
int x = optionalInt.orSome(0);
And you can replace this...
if (myString != null && !"".equals(myString))
...with this, if you have an Option<String>...
for (String s : myOptionString)
There's some support for a #Nullable and #NotNull annotation in IntelliJ IDEA. There's also some talk about adding those annotations (or a similar feature) to Java 7. Unfortunately I don't know how far that got or if it's still on track at all.
Indeed: in our framework we have a 'non-null' pointer type, which may be returned to indicate that the method will always return a value.
I see three options:
wait for language support to express it (e.g. the C# ?! thing)
use Aspect Orientation to build your own language extensions to express it
use a custom type to express it
(but builds on developer cooperation) use a naming scheme to indicate it
For Java, one can use the Javadoc description of a method to document the meaning of the returned value, including whether it can be null. As has been mentioned, annotations may also provide assistance here.
On the other hand, I admit that I don't see null as something to be feared. There are situations in which "nobody's home" is a meaningful condition (although the Null Object technique also has real value here).
It is certainly true that attempting a method invocation on a null value will cause an exception. But so will attempting to divide by zero. That doesn't mean that we need to go on a campaign to eliminate zeroes! It just means that we need to understand the contract on a method and do the right thing with the values that it returns.
Have you had a look at Spec#?
You could write your own annotation (Java) or attribute (C#) to indicate that the return value might be null. Nothing will automatically check it (although .NET 4.0 will have code contracts for this sort of thing) but it would at least act as documentation.
Maybe you could define a generic class named "NotNull", so that your method might be like:
public NotNull<Object> methodWhichCannotReturnNull(int i) throws Exception
{
// the following would lead to a run-time error thown by the
// NotNull constructor, if it's constructed with a null value
return new NotNull<Object>(null);
}
This is still a run-time (not a compile-time) check, but:
It's thrown in the implementation of the method (it's not a fault in the calling code)
It's self-documenting (the caller knows he's geting NotNull<T> as a return type)
At all costs, avoid relying on the JavaDocs. People only read them if the signature doesn't appear trivial and self-explanatory (Which is bad to begin with), and these who actually bother to read them are less likely to make a mistake with the nulls since they are currently being more careful.
If you're using Java 5+, you can use a custom Annotation, e.g. #MayReturnNull
UPDATE
All coding philosophy aside (returning null, using exceptions, assertions, yada yada), I hope the above answers your question. Apart from primitives having default values, complex types may or may not be null, and your code needs to deal with it.
Generally speaking, I would assume that a null return value is against the contract of the API by default. It is almost always possible to design your code such that a null value is never returned from your APIs during "normal" flow of execution. (For example, check foo.contains(obj) rather then calling foo.get(obj) and having a separate branch for null. Or, use the Null object pattern.
If you cannot design your API in such a way, I would clearly document when and why a null could be thrown--at least in the Javadoc, and possibly also using a custom #annotation such as several of the other answers have suggested.