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
?
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. PracticallyFor 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.
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 ofRuntimeException
. Like other classes that have a parent ofRuntimeException
, they are considered unchecked - so code compiles even if it's going to produce an NPE: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.
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 entirecalling 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 thee.printStackTrace()
Now
NullPointerException
is a runtime exception, which basically points to some logical fallacy in the code. There are times when youmay
want to catch it. But as a thumbrule: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()
returnednull
you may catch NPE on trying to call some method of thecar
, or check if the car isnull
and throwRuntimeException
(but only if the situation is really exceptionable). Thus you make errors more abstract-binded and easier to understand.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.
You dont have to actually do
e.printstacktrace()
all the time , you can specify your own body message using logger orSystem.out.println()