When is it OK to catch NullPointerException? - java

Effective java recommends that we shouldn't catch NullPointerException.
Is it always right?
In many cases of catching NullPointerException, catch body only calls printStackTrace().
If I don't catch NullPointerException and call printStackTrace(), how I can check the place where the exception occurred?
And also if I catch NullPointerException and the catch body is empty, we cannot get any stack information at that time, can we?
UPDATE
I analyzed statistics of catching RuntimeException in google android source, AOSP4.2.2_r1.2.
There are 249 RuntimeException catchings and followings are statistics of catch-body.
42%: throw it again as other Exceptions (RuntimeException: 33%, others: 8%)
32%: just return null or 0/false/true or other default values
14%: just call log or printstacktrace
5%: just comment like "// Fall through.", "// ignore, not a valid type.", "// system process dead", "// do nothing"
2%: empty body
3%: display error messages or send fail codes (ex. network service discovery failed: replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, NsdManager.FAILURE_INTERNAL_ERROR); )
3%: intialize or reset related variables.
In almost cases, dalvik and external handle NPE by throwing other Exceptions.
But frameworks usually handle by returning null or other values.
Do you think that throwing other Exceptions in catch-body is not bad or good handling?
If NPE occured in higher levels(ex. applications) and the developer confirms the exception is not critical because the app is fully independent, can I accept for our developer to ignore the NPE by catching?
and one more thing,
Can I conclude that google android framework source code may be some unstable in aspects of RuntimeException?

Effective java recommend that we shouldn't catch NullPointerException. Is it always right?
In nearly all cases it is correct.
NullPointerException is usually a result of a bug; i.e. your application encountered a null object reference in a situation where it was not anticipated, and then attempted to use it. In this scenario, since you (the programmer) did not anticipate the null, it is next to impossible to know whether it is safe to attempt to recover, and / or to know what "remediation" might be required. So the best thing to do is to let the NPE propagate to the base level, and then treat it as a generic bug. (In "network service" applications, it may be appropriate to return a "service error" response, and attempt to continue.)
The other scenario is where you (the programmer) anticipate that a null might be delivered. In this case, the best strategy is (nearly always) to explicitly test for the null before you attempt to use it, thereby avoiding the NPE ... and the need to handle it. There are two reasons for this:
Exception handling is typically expensive. Indeed it can be many orders of magnitude more expensive than testing for a null.
If you allow the expected NPE to happen and then catch it, you are liable to also catch other unexpected NPEs ... and handle them incorrectly.
Note that I qualified the above by saying "nearly always". It is theoretically possible to have a scenario where explicit tests for null clutter up your code so much that it is at least worth considering allowing the NPE to happen. However, there is still the possibility of unexpected NPEs as well ... depending on the code. So this approach is always potentially fragile.
(FWIW - I've never encountered a real case where this would be a good idea ...)
In many cases of catching NullPointerException, catch body only calls printStackTrace().
That is probably bad code. Doing nothing is rarely the correct way to recover from an NPE.
If I don't catch NullPointerException and call printStackTrace(), how I can check the place where the exception occurred?
You let the NPE propagate to the base level. There you catch and print (or log) a stacktrace for all unhandled exceptions, and then either bail out or attempt to recover ... if that is feasible.
And also if I catch NullPointerException and the catch body is empty, we cannot get any stack information at that time, can we?
Never, ever do this! It is called "squashing" and is dangerous. (Especially since, as I explained above, the NPE may be due to something that you / your code did not anticipate.)
And no, if you do this, you can't get the stack trace. It is gone.
FOLLOWUP
I don't place much trust / faith on some general strategies for "avoiding NPEs"1. For instance stuff like this:
return (someObject != null) ? someObject.toString() : "";
always make me suspicious that the programmer is not thinking about the problem. Why was someObject a null in the first place?
A NPE is caused by having a null in place where you don't expect it. As such, NPEs are usually symptoms of a problem rather than the actual problem itself. To my mind, NPEs are not something to be avoided. Rather, you should be using the NPEs to find and fix the root cause of the unexpected null. Code like the above that avoids the NPE gets in the way of that goal.
So I prefer / recommend strategies for avoiding null values in unexpected places.
Make sure that every reference field is gets initialized to a non-null value ... unless null is a meaningful value.
Try to avoid having null as a meaningful value, especially if there is an alternative. For instance, an empty String, a zero length array, an empty collection, a distinguished instance that means "undefined" or whatever. Or, for Java 8 and later, use Optional.
Don't return null as an error or an indication of a special case. (Throw an exception or return a distinguished value.)
Check early for unanticipated null values (e.g. null arguments), and throw the NPE sooner rather than later.
In the few places where a null argument or result is legitimate, make sure that your javadocs document this clearly and explicitly. If there is no documentation, then the implication should be that null is not allowed and won't be returned.
And wherever you get an NPE, make sure that you find and fix the real source of the problem ... not just the specific statement that threw the exception.
1 - There is value in knowing about places in the standard Java APIs where null is used (or abused) as a return value. For instance, Class.getResourceAsStream(...) or HttpRequest.getParam(...). Those "advice for avoiding NPE" documents are useful in as much that they point out these traps.

NullPointerException typically occurs due to logical errors in our code. We can eliminate NullPointerException by avoiding unsafe operations. If any NullPointerException still happens, you can see it in StackTrace.
For example
if (Obj.getName("Sam")) {
// only executes if Obj != null
}
We can avoid NullPointerException as follows
if (Obj == null){
System.out.println("Null Obj, Can't proceed");
} else {
Obj.getName("Sam")
}

Generally It is recommend that one should not catch NullPointerException and let it be handled by JVM.
But it all depends,
Say for eg: if you have code like List<Student> listStudent = getAllStudent();
here getAllStudent() connects to DB and give you result, Here before doing any operation on list object you should check that
if(listStudent != null){
//do the task.
}else{
//Show Message like no student is there instead of catching NullPointerException
}
if you will not do, then chances are there that NullPointerException can occur if no data is there.
so better practice is to check for Nulls but not handle it like
try{
}catch(NullPointerException e){
}

You definetly should not use empty catch block without REALLY IMPORTANT reason. Usually there is no such reason.
Usually it's good either to check if variable is null or catch NPE and trow more appropriate reason. For example if a method getCar() returned null you may catch NPE on trying to call some method of the car, or check if the car is null and throw RuntimeException(but only if the situation is really exceptionable). Thus you make errors more abstract-binded and easier to understand.

When an exception is thrown, be it any exception, jvm looks for the closest handler(catch block). If it is not found in the current method, it looks for the handler in the calling code and so on. SO basically the entire calling stack is searched bottom-up to look for a catch block which can handle the said exception. If no handler is found jvm uses the default handler which calls the e.printStackTrace()
Now NullPointerException is a runtime exception, which basically points to some logical fallacy in the code. There are times when you may want to catch it. But as a thumbrule:
don't catch runtime exceptions, they generally point to logical errors
don't leave an empty catch block, you will lose the stacktrace and the exception if you catch it but do not act upon it.
don't just print the stacktrace to standard outout, instead log it somewhere for later analysis, if needed

The convention is to avoid catching any sort of runtime exception. The reason being: something horrible has gone wrong, and you as a developer should be keen on fixing it thirty minutes ago.
NullPointerException is, in fact, a subclass of RuntimeException. Like other classes that have a parent of RuntimeException, they are considered unchecked - so code compiles even if it's going to produce an NPE:
// This would appropriately return "false", if the order were reversed
// and something was empty.
public boolean doSomething(String something) {
String hello = null;
if(hello.equals(something)) {
System.out.println("Wow");
}
}
Explicitly catching any sort of runtime exception indicates that you expect horrible, bad things to happen over the course of the program, and you wish to gloss over that fact.
As for what goes in the body of the catch block...that's probably being automatically generated by your IDE. If you're not propagating the exception to the higher levels of your application, then you need to get useful context as to why your program blew up.
If you don't put anything in the catch block, it's silently ignored - which is bad.

Usually NullPointerException signifies a logical error in the API usage or exepcted value is missing. That's why it's recommended to to throw it back. However you can catch it. Practically
I will suggest you to catch when you want to give default values for
the passed null parameters.
For example :
You are expecting timeout value to be configurable and you expect that user has to pass it. However user forgets to pass it. In this scenario you can catch the NPE and log a warning that you are using the default value for the parameter.

NullPointerException is a situation in code where you try to access/ modify an object which has not been initialized yet.
It essentially means that object reference variable is not pointing anywhere and refers to nothing or ‘null’.
Joshua bloch in effective java says that:
“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.”
So, if you must allow NullPointerException in some places in you code then make sure you make them more informative then they usually are.
Read more about Effective NPE Handling from here:
http://marxsoftware.blogspot.in/2009/04/effective-java-nullpointerexception.html
http://howtodoinjava.com/2013/04/05/how-to-effectively-handle-nullpointerexception-in-java/

You dont have to actually do e.printstacktrace() all the time , you can specify your own body message using logger or System.out.println()

Robust, user centric code should try to catch such a 'FATAL ERROR' if there is anything ANYTHING at all you could do about it. You could retry the attempted function call. Perhaps this null exception is due to something transient. Something that really shouldn't throw an exception and should be coded better for the transient failure but, which, however should not deter the end user from getting what he wants, instead of abandoning what could be a lengthy stateful form input process, and only on the last, completely insignificant step, like entering the users's email preference or something does the null pointer error occur and trash the user's existing input.

Related

Why explicitly throw a NullPointerException rather than letting it happen naturally?

When reading JDK source code, I find it common that the author will check the parameters if they are null and then throw new NullPointerException() manually.
Why do they do it? I think there's no need to do so since it will throw new NullPointerException() when it calls any method. (Here is some source code of HashMap, for instance :)
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (remappingFunction == null)
throw new NullPointerException();
Node<K,V> e; V oldValue;
int hash = hash(key);
if ((e = getNode(hash, key)) != null &&
(oldValue = e.value) != null) {
V v = remappingFunction.apply(key, oldValue);
if (v != null) {
e.value = v;
afterNodeAccess(e);
return v;
}
else
removeNode(hash, key, null, false, true);
}
return null;
}
There are a number of reasons that come to mind, several being closely related:
Fail-fast: If it's going to fail, best to fail sooner rather than later. This allows problems to be caught closer to their source, making them easier to identify and recover from. It also avoids wasting CPU cycles on code that's bound to fail.
Intent: Throwing the exception explicitly makes it clear to maintainers that the error is there purposely and the author was aware of the consequences.
Consistency: If the error were allowed to happen naturally, it might not occur in every scenario. If no mapping is found, for example, remappingFunction would never be used and the exception wouldn't be thrown. Validating input in advance allows for more deterministic behavior and clearer documentation.
Stability: Code evolves over time. Code that encounters an exception naturally might, after a bit of refactoring, cease to do so, or do so under different circumstances. Throwing it explicitly makes it less likely for behavior to change inadvertently.
It is for clarity, consistency, and to prevent extra, unnecessary work from being performed.
Consider what would happen if there wasn't a guard clause at the top of the method. It would always call hash(key) and getNode(hash, key) even when null had been passed in for the remappingFunction before the NPE was thrown.
Even worse, if the if condition is false then we take the else branch, which doesn't use the remappingFunction at all, which means the method doesn't always throw NPE when a null is passed; whether it does depends on the state of the map.
Both scenarios are bad. If null is not a valid value for remappingFunction the method should consistently throw an exception regardless of the internal state of the object at the time of the call, and it should do so without doing unnecessary work that is pointless given that it is just going to throw. Finally, it is a good principle of clean, clear code to have the guard right up front so that anyone reviewing the source code can readily see that it will do so.
Even if the exception were currently thrown by every branch of code, it is possible that a future revision of the code would change that. Performing the check at the beginning ensures it will definitely be performed.
In addition to the reasons listed by #shmosel's excellent answer ...
Performance: There may be / have been performance benefits (on some JVMs) to throwing the NPE explicitly rather than letting the JVM do it.
It depends on the strategy that the Java interpreter and JIT compiler take to detecting the dereferencing of null pointers. One strategy is to not test for null, but instead trap the SIGSEGV that happens when an instruction tries to access address 0. This is the fastest approach in the case where the reference is always valid, but it is expensive in the NPE case.
An explicit test for null in the code would avoid the SIGSEGV performance hit in a scenario where NPEs were frequent.
(I doubt that this would be a worthwhile micro-optimization in a modern JVM, but it could have been in the past.)
Compatibility: The likely reason that there is no message in the exception is for compatibility with NPEs that are thrown by the JVM itself. In a compliant Java implementation, an NPE thrown by the JVM has a null message. (Android Java is different.)
Apart from what other people have pointed out, it's worth noting the role of convention here. In C#, for example, you also have the same convention of explicitly raising an exception in cases like this, but it's specifically an ArgumentNullException, which is somewhat more specific. (The C# convention is that NullReferenceException always represents a bug of some kind - quite simply, it shouldn't ever happen in production code; granted, ArgumentNullException usually does, too, but it could be a bug more along the line of "you don't understand how to use the library correctly" kind of bug).
So, basically, in C# NullReferenceException means that your program actually tried to use it, whereas ArgumentNullException it means that it recognized that the value was wrong and it didn't even bother to try to use it. The implications can actually be different (depending on the circumstances) because ArgumentNullException means that the method in question didn't have side effects yet (since it failed the method preconditions).
Incidentally, if you're raising something like ArgumentNullException or IllegalArgumentException, that's part of the point of doing the check: you want a different exception than you'd "normally" get.
Either way, explicitly raising the exception reinforces the good practice of being explicit about your method's pre-conditions and expected arguments, which makes the code easier to read, use, and maintain. If you didn't explicitly check for null, I don't know if it's because you thought that no one would ever pass a null argument, you're counting it to throw the exception anyway, or you just forgot to check for that.
It is so you will get the exception as soon as you perpetrate the error, rather than later on when you're using the map and won't understand why it happened.
It turns a seemingly erratic error condition into a clear contract violation: The function has some preconditions for working correctly, so it checks them beforehand, enforcing them to be met.
The effect is, that you won't have to debug computeIfPresent() when you get the exception out of it. Once you see that the exception comes from the precondition check, you know that you called the function with an illegal argument. If the check were not there, you would need to exclude the possibility that there is some bug within computeIfPresent() itself that leads to the exception being thrown.
Obviously, throwing the generic NullPointerException is a really bad choice, as it does not signal a contract violation in and of itself. IllegalArgumentException would be a better choice.
Sidenote:
I don't know whether Java allows this (I doubt it), but C/C++ programmers use an assert() in this case, which is significantly better for debugging: It tells the program to crash immediately and as hard as possible should the provided condition evaluate to false. So, if you ran
void MyClass_foo(MyClass* me, int (*someFunction)(int)) {
assert(me);
assert(someFunction);
...
}
under a debugger, and something passed NULL into either argument, the program would stop right at the line telling which argument was NULL, and you would be able to examine all local variables of the entire call stack at leisure.
It's because it's possible for it not to happen naturally. Let's see piece of code like this:
bool isUserAMoron(User user) {
Connection c = UnstableDatabase.getConnection();
if (user.name == "Moron") {
// In this case we don't need to connect to DB
return true;
} else {
return c.makeMoronishCheck(user.id);
}
}
(of course there is numerous problems in this sample about code quality. Sorry to lazy to imagine perfect sample)
Situation when c will not be actually used and NullPointerException will not be thrown even if c == null is possible.
In more complicated situations it's becomes very non-easy to hunt down such cases. This is why general check like if (c == null) throw new NullPointerException() is better.
It is intentional to protect further damage, or to getting into inconsistent state.
Apart from all other excellent answers here, I'd also like to add a few cases.
You can add a message if you create your own exception
If you throw your own NullPointerException you can add a message (which you definitely should!)
The default message is a null from new NullPointerException() and all methods that use it, for instance Objects.requireNonNull. If you print that null it can even translate to an empty string...
A bit short and uninformative...
The stack trace will give a lot of information, but for the user to know what was null they have to dig up the code and look at the exact row.
Now imagine that NPE being wrapped and sent over the net, e.g. as a message in a web service error, perhaps between different departments or even organizations. Worst case scenario, no one may figure out what null stands for...
Chained method calls will keep you guessing
An exception will only tell you on what row the exception occurred. Consider the following row:
repository.getService(someObject.someMethod());
If you get an NPE and it points at this row, which one of repository and someObject was null?
Instead, checking these variables when you get them will at least point to a row where they are hopefully the only variable being handled. And, as mentioned before, even better if your error message contains the name of the variable or similar.
Errors when processing lots of input should give identifying information
Imagine that your program is processing an input file with thousands of rows and suddenly there's a NullPointerException. You look at the place and realize some input was incorrect... what input? You'll need more information about the row number, perhaps the column or even the whole row text to understand what row in that file needs fixing.

Shouldn't catch NPE but don't know how to handle the NULL

I know that NPE is not recommended to be caught, however the NPE is in a method whose return value is a boolean based on the variable where the NPE comes from.
Code is something like this:
public static boolean isStale() {
return a.get(); //a==null causing NPE
}
In my case, I don't really know what to return without the info of a.
What should I do? What kind of exception should I throw, if any?
Edit:
1. returning true or false will be inaccurate because the result really depends on the info inside a.
a is acctually from a service call client.getA()
There is no reason why you should prevent your code from throwing exceptions. Just consider your case : you say yourself that the behaviour of your method is not defined in the case a == null, so why should you handle it ? It will only lead to weird behaviours and your users might be surprised that their code failed or produce unexpected results somewhere whereas their calls into your API went fine.
Exceptions are specially designed to address this kind of things, so make good use of it. You can either throw a new, custom exception to add some API-specific semantic, or let the NPE be propagated to the caller.
For example :
public static boolean isStale() {
if (a == null) throw new IllegalStateException("a should not be null");
return a.get();
}
However, it is more likely that you should do that in a constructor (because I assume a is an attribute). In a constructor, I would opt for IllegalArgumentException.
First you need to ask yourself: Is it normal for a to ever be null?
If yes, then throwing an exception is rarely a good idea. Exceptions should really only be thrown when something unexpected occurs. It then really is up to you to decide what this means for your program. Does it make sense to return some default value in this case?
return a == null ? false : a.get(); // return false as a default value?
If no (more likely):
... then ask the following question: Why am I getting a null value?
If it's because you coded a bug: then you don't need to do anything. Just let it throw a NullPointerException. There really is no point in catching the exception and pretending everything is alright, if clearly, a basic invariant in your program has been broken. Better to let it throw the exception early and focus your energies on understanding and fixing the bug asap. Trying to handle the exception will only cause your program to fail at some other more unexpected point in time, and will become that much harder to debug.
If, on the other hand, it's because of some external entity feeding you bad data over which you really have no control: then this could be a good case for throwing a custom exception that can be used to provide a more meaningful error message to either the user or the developer. But even in this case, it's probably a better idea to have a validated for a null value more "upstream" and have it throw an exception as early as possible. It doesn't feel like it should be part of the isStale() method's contract to worry about the correctness of a's value.
Interesting reading, geared towards C#, but the principles apply just as well to Java: Vexing exceptions.
This depends on what isStale() determines. You can try/catch this method and catch the NullPointerException. I don't believe this violates best practices if you really have no way to handle a being null. You could also instantiate a new a if a is null, or throw your own Exception.
There's no need to throw any Exception just make sure a isn't null before using it, use a simple conditional statement:
public static boolean isStale() {
a!=null ? return a.get() : return false;
}
In the case where returning false will be irrelevant, you can just change the return type of your method to String and return a warning or any other significant message :
public static String isStale() {
a!=null ? return a.get().toString() : return "NULL";
}
Take a look at this: Best approach to converting Boolean object to string in java

When debugging with Eclipse what are the best ways to track down Null Pointer Exceptions?

We're having trouble tracking down Null Pointer Exceptions in our code using Eclipse and I was wondering if Eclipse offered any help in this area. What ways does Eclipse offer to easily track down Null Pointer Exceptions?
To illustrate, here is a typical code example that is throwing an NPE:
if (myObject.getDimensionMap().get(keyValue.getConcept()).isMeasureDimension()) {
Unless I'm mistaken there are 5 possibilities where an object could be null:
myObject could be null
myObject.getDimensionMap could be null
keyValue could be null
keyValue.getConcept could be null
myObject.getDimensionMap().get(keyValue.getConcept) could be null
Avoiding the argument of changing the code so each statement is on a different line, does Eclipse offer any way of helping to find the NPE without having to step into each statement? Bear in mind that it took the dev team quite a while to even get to this statement let alone find out which one of the elements was null (it was the getDimensionMap().get ).
Update:
It took so long to find the actual cause of the NPE because the offending code was buried in a deep call hierarchy, where the outer layer has a catch for all exceptions. The reason for this is so that the exceptions can then be rendered in a more attractive format and displayed to the user. So the code is like
try {
doSomething
...
callSomething
callSomethingElse
...
offending if test which throws the NPE
...
} catch (Exception e) {
// Format exception and pass back to client
}
Of course, the user never want to see the phrase NullPointerException....
Thanks.
From Eclipse, Run/Add java Exception Breakpoint.
Select NullPointerException. Ensure 'suspend on caught exception' is ticked.
Only downside is it will trigger on any code that intentionally raises and catches NPEs internally.

On Asserts and Exceptions; Java

In this specific scenarios, are asserts more appropriate then exceptions?
It is my understanding that assert should be used when program is FUBAR to a degree where it can not recover and will exit.
I also was told to always throw exceptions for clarity and error message handling.
Is there a fine line between when to use each? Is there an example where assert must be used in place of exception unconditionally?
public void subscribe(DataConsumer c) throws IllegalArgumentException {
if (c == null) {
// Almost certainly FUBAR
throw new IllegalArgumentException("Can't subscribe null as a DataConsumer. Object not initialized");
}
if (dataConsumerList == null) {
// Definetely FUBAR
throw new IllegalArgumentException("Nothing to subscribe to. DataConsumerList is null");
}
dataConsumerList.add(c);
}
Personally I'm not keen on using assertions for this sort of thing, simply because they can be turned off. Some places use assertions when running tests, but then disable them for production for the sake of speed. To me this is like taking your driving test as normal, but then removing your seatbelt when you get on the motorway.
An assertion is only going to throw an exception anyway, of course. If you absolutely want to take the JVM down right now, you'd need to use something like Runtime.halt.
So I'm a fan of exceptions here, although I'd typically use a NullPointerException when given a null argument, and if dataConsumerList is part of your state then I would personally use IllegalStateException to differentiate that situation. (It's a shame that Java doesn't have the same ArgmentNullException that .NET has, given what a common check it is.)
Guava has the useful Preconditions class which lets you write this more concisely:
public void subscribe(DataConsumer c) throws IllegalArgumentException {
Preconditions.checkNotNull(c,
"Can't subscribe null as a DataConsumer. Object not initialized");
Preconditions.checkState(dataConsumerList != null,
"Nothing to subscribe to. DataConsumerList is null");
dataConsumerList.add(c);
}
General rule (copied from here)
assertions should protect from (not always obvious) mistakes of the
developer, e.g. using a pointer despite its being NULL.
exceptions are a way to handle errors that may legitimately occur at
runtime, e.g. the failure of trying to connect to some server (which may
not respond for various reasons).
And there is a better way of writing the above code using google-guava Preconditions.checkNotNull() class.
public void subscribe(DataConsumer c) throws IllegalArgumentException
{
checkNotNull(c, "Can't subscribe null as a DataConsumer. Object not initialized");
checkNotNull(dataConsumerList , "Nothing to subscribe to. DataConsumerList is null");
dataConsumerList.add(c);
}
If you could put this in English terms, use assert for "gotta" (Got to, Must) and exceptions for "otta" (Ought to, should).
Use the assert for show-stopping, critical conditions that must be true for the execution to continue. Examples might be that a division happens correctly (think of the Intel chip floating point bug) or that your database connection is not null after you have correctly opened it. If these have occurred, then program execution should not continue.
Use the throw for foreseeable errors that your method may handle. The throw is a part of a contract that declares to you and other programmers that certain types of errors may be encountered (and that it's not your responsibility).
In your example, my guess is that a null consumer or an empty list should never happen under normal circumstances. If my guess is correct, then you would want to use an assert here, declaring that subscribe() will handle it.
If my guess is wrong and a null consumer happens, say 1 out of 50 times, then the throw would be better and you would be declaring that subscribe() forms a contract with a calling method, whereby the calling method handles the error.
The Java technote Programming With Assertions contain this explicit line in with regards to usage:
Do not use assertions for argument checking in public methods.
That should be a pretty definitive answer to your question.

Is returning null after exception is caught bad design [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return. The following code snippet illustrates my problem.
public Object getObject(){
try{
...
return object;
}
catch(Exception e){
//I have to return something here but what??
return null; // is this a bad design??
}
}
So my questions are:
Is return null bad design?
If so what is seen as a cleaner solution??
thanks.
I would say don't catch the exception if you really can't handle it. And logging isn't considered handling an error. Better to bubble it up to someone who can by throwing the exception.
If you must return a value, and null is the only sensible thing, there's nothing wrong with that. Just document it and make it clear to users what ought to be done. Have a unit test that shows the exception being thrown so developers coming after you can see what the accepted idiom needs to be. It'll also test to make sure that your code throws the exception when it should.
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return.
If you don't know what to return, then it means that you don't know how to handle the exception. In that case, re-throw it. Please, don't swallow it silently. And please, don't return null, you don't want to force the caller of the code to write:
Foo foo = bar.getFoo();
if (foo != null) {
// do something with foo
}
This is IMHO a bad design, I personally hate having to write null-checks (many times, null is used where an exception should be thrown instead).
So, as I said, add a throws clause to the method and either totally remote the try/catch block or keep the try/catch if it makes sense (for example if you need to deal with several exceptions) and rethrow the exception as is or wrap it in a custom exception.
Related questions
How to avoid “!= null” statements in Java?
Above all I prefer not to return null. That's something that the user has to explicitly remember to handle as a special case (unless they're expecting a null - is this documented). If they're lucky they'll deference it immediately and suffer an error. If they're unlucky they'll stick it in a collection and suffer the same problem later on.
I think you have two options:
throw an exception. This way the client has to handle it in some fashion (and for this reason I either document it and/or make it checked). Downsides are that exceptions are slow and shouldn't be used for control flow, so I use this for exceptional circumstances (pun intended)
You could make use of the NullObject pattern.
I follow a coding style in which I rarely return a null. If/when I do, that's explicitly documented so clients can cater for it.
Exceptions denote exceptional cases. Assuming your code was supposed to return an object, something must have gone wrong on the way (network error, out of memory, who knows?) and therefore you should not just hush it by returning null.
However, in many cases, you can see in documentation that a method returns a null when such and such condition occurs. The client of that class can then count on this behaviour and handle a null returned, nothing bad about that. See, in this second usage example, it is not an exceptional case - the class is designed to return null under certain conditions - and therefore it's perfectly fine to do so (but do document this intended behaviour).
Thus, at the end of the day, it really depends on whether you can't return the object because of something exceptional in your way, or you simply have no object to return, and it's absolutely fine.
I like the responses that suggest to throw an exception, but that implies that you have designed exception handling into the architecture of your software.
Error handling typically has 3 parts: detection, reporting, and recovery. In my experience, errors fall into classes of severity (the following is an abbreviated list):
Log for debug only
Pause whatever is going on and report to user, waiting for response to continue.
Give up and terminate the program with an apologetic dialogue box.
Your errors should be classified and handling should be as generically and consistently as possible. If you have to consider how to handle each error each time you write some new code, you do not have an effective error handling strategy for your software. I like to have a reporting function which initiates user interaction should continuation be dependent on a user's choice.
The answer as to whether to return a null (a well-worn pattern if I ever saw one) then is dependent on what function logs the error, what can/must the caller do if the function fails and returns the null, and whether or not the severity of the error dictates additional handling.
Exceptions should always be caught by the controller in the end.
Passing a <null> up to the controller makes no sense.
Better to throw/return the original exception up the stack.
It's your code and it's not bad solution. But if you share your code you Shoudn't use it because it can throw unexpected exception (as nullpointer one).
You can of course use
public Object getObject() throws Exception {}
which can give to parent function usable information and will warn that something bad can happen.
Basically I would ditto on Duffymo, with a slight addition:
As he says, if your caller can't handle the exception and recover, then don't catch the exception. Let a higher level function catch it.
If the caller needs to do something but should then appropriately die itself, just rethrow the exception. Like:
SomeObject doStuff()
throws PanicAbortException
{
try
{
int x=functionThatMightThrowException();
... whatever ...
return y;
}
catch (PanicAbortException panic)
{
cleanUpMess();
throw panic; // <-- rethrow the exception
}
}
You might also repackage the exception, like ...
catch (PanicAbortException panic)
{
throw new MoreGenericException("In function xyz: "+panic.getMessage());
}
This is why so much java code is bloated with if (x!=null) {...} clauses. Don't create your own Null Pointer Exceptions.
I would say it is a bad practice. If null is received how do I know if the object is not there or some error happened?
My suggestion is
never ever return NULL if the written type is an array or
Collection. Instead, return an empty Collection or an empty array.
When the return type is an object, it is up to you to return null depending on the scenario. But never ever swallow an exception and return NULL.
Also if you are returning NULL in any scenario, ensure that this is documented in the method.
As Josha Blooch says in the book "Effective Java", the null is a keyword of Java.
This word identifies a memory location without pointer to any other memory location: In my opinion it's better to coding with the separation of behavior about the functional domain (example: you wait for an object of kind A but you receive an object of kind B) and behavior of low-level domain (example: the unavailability of memory).
In your example, I would modify code as :
public Object getObject(){
Object objectReturned=new Object();
try{
/**business logic*/
}
catch(Exception e){
//logging and eventual logic leaving the current ojbect (this) in a consistent state
}
return objectReturned;
}
The disadvantage is to create a complete Object in every call of getObject() (then in situation where the object returned is not read or write).
But I prefer to have same object useless than a NullPointerException because sometimes this exception is very hard to fix.
Some thoughts on how to handle Exceptions
Whether returning null would be good or bad design depends on the Exception and where this snippet is placed in your system.
If the Exception is a NullPointerException you probably apply the catch block somewhat obtrusive (as flow control).
If it is something like IOException and you can't do anything against the reason, you should throw the Exception to the controller.
If the controller is a facade of a component he, translate the Exception to well documented component-specific set of possible Exceptions, that may occur at the interface. And for detailed information you should include the original Exception as nested Exception.

Categories