Consider this code:
x = Repo.GetX(13);
Services.Process(x);
I could check that x is null before processing it, or I could have Services.Process() throws an exception if X is null and use a try/catch block.
Which method is preferable?
(Or should I do both, just in the exceptional case that x becomes null somehow from the point of its retrieval to processing it?)
If you’re trying to decide between:
or
Then be aware that they don’t mean the same thing. The first one catches any NullPointerException thrown by
Process. The second one only handles the case wherexitself is NULL – ifProcessdoesx.foo().bar(), andx.foo()returns NULL, it isn’t handled.You should decide between the two based on what errors you can handle.
In the case where
Services.Processis documented to throw NullPointerException if and only ifxis NULL, so that (assuming we believe the documentation) the two do mean the same thing, then I’d do the second one. That way, if the documentation is lies, and there’s a bug inServices.Processthat makes it throw in some other situation, then we will not erroneously handle/report the exception as thoughxwere NULL when in fact it is not.So, catch and suppress an exception in two situations:
Don’t catch just because you know one situation that could cause the exception, and can handle that, when the same exception could be thrown for other reasons. I suppose you could do:
But that seems to me needlessly verbose in this case: since we can check in advance whether
xis null, we might as well. There are cases, though, where you catch an exception because it’s impossible or just silly to try to predict in advance whether it will occur or not:We could check whether
sis a valid number before callingparseFloat, but that would basically be doing the same work twice – checking a string is a valid float is pretty much the same as actually converting it. So it makes sense to catch this exception – we know what it means, we know what to do about it, we couldn’t realistically have prevented it from happening.(Or you could use DecimalFormat.parse, which doesn’t throw at all)