You asked for didactic examples. What I have is what I learned from experience.
In the case of checked exceptions I see that data manipulation libraries commonly throw I / O-related and data-parsing exceptions. The classic Java I / O library, for example, throws IOException
, FileNotFoundException
and EOFException
, to name the most common. Net networking libraries and HTTP communication because they also perform I / O throw at least IOException
. A JSON parser such as json.org that comes along with Android may throw a JSONException
related to reading a data from a JSON string, and Google Gson may cast a JsonSyntaxException
. >
Finally, these are situations in which the library itself is not ready to deal with the error and chooses to pass it on to a higher level of call stack or call stack . It does this by declaring that such exceptions, if they occur, will need to be handled by those who make use of that API. This is one of the advantages of working with exceptions: just as you can treat them at the point they occur, you can also delegate this treatment to a level that is better able to treat or "recover" from the error that occurred.
When declaring this in the form of a checked exception , you are signaling the "user" code that that error deserves attention and probably some kind of handling. And typically it's a "recoverable" error: Your application can prepare for a malformed JSON, a missing file, or an interruption in network communication.
It is different from a runtime exception in that the runtime typically represents an error in the operation of the code itself, an error that you catch while executing and needs fix the code and prevent it from happening, as @bigown said. You need to "armor" your code against it. A parameter that can not be passed as null
otherwise it will throw a IllegalArgumentException
or a NullPointerException
, a state that theoretically should not happen under penalty of throwing a IllegalStateException
(example: a method that should only be called by thread from Android UI and you involuntarily call from a secondary thread), to name the types I most use currently. When my code throws one of these exceptions, I'll admit that I do not expect them to happen, but sometimes they happen and I know it's a code defect.
I confess that I have already dealt with IOException
inside a library of my call to web services instead of delegating to the user code. I "swallowed" the exception (at most logged in) and returned null
in my answer. It was a terrible design decision. My user code did not know when a null
came from a successful request or when it came from an I / O error, and are two different situations that require different treatment. It was not my library that needed to handle I / O exceptions, but the code that made use of it.
In a more recent code where I use the Apache HTTP Client, I declare the following:
private HttpResponse executarRequisicaoSincrona(DataTransferRequest requisicao)
throws UnsupportedEncodingException, IOException {
See how this method delegates to another level two checked exceptions , a specific I / O (which is an unsupported encoding) and a more generic I / O. The two are likely to occur during an HTTP request in different situations and I found it fine not to treat them at the same level as they are launched but rather to pass them forward because at that time my code does not yet know what to do with they. If I did, I could treat them within the executarRequisicaoSincrona
method instead of declaring them, but that's not the case in my code.
I hope with these experiments you can have a more precise notion of when to use or throw exceptions of the two types, checked and unchecked .
Update: This link explains very well the difference between the two and when to use one or the other (in fact it explains the best practices about handling exceptions in Java). I strongly recommend it: link