Exception vs Runtimeexception, when using one or the other?

Asked

Viewed 11,135 times

5

I was with that doubt, and when I was made aware of it another came to me, which I would like to be clarified.

  • What’s the difference between Exception and RuntimeException?
  • When to use Exception or RuntimeException?

If possible a didactic example of the use of Exception and RuntimeException.

2 answers

7


RuntimeException should be used when the exception can be prevented. Use it indirectly when you want to signal to the user programmer of your code that it can try to solve the problem when this exception is thrown. Because of this it is considered an unchecked exception.

They are often used in programming errors that can only be checked at runtime, so you don’t have to capture them. Programming error should let the application break. They only occur because they were not prevented before it happened, so they are called programming errors. A check before the error occurs will solve the problem. Examples of errors of this type are ArrayIndexOutOfBoundsException and NullPointerException.

Nothing prevents you from creating your own derivatives of this class. You just don’t want to do this because you don’t want to take the trouble to capture it later. The philosophy of Java is that whenever it is possible to do something with the problem, an exception should be captured, so this type of exception should be avoided as much as possible. This does not mean that any exception should be captured. Even the checked exceptions often the best is to delegate to another method. And unverified ones should only be captured if in that context you can do something to recover from the error, even if it is to present a custom message.

For mistakes that must be prevented using Exception which is more generic and involves any exception, including it can be a RuntimeException since all exceptions must be derived from Exception. It is also used indirectly. It is considered a checked exception. That is, all exceptions that are not RuntimeException are checked. Examples are all derived and the IOException or DataFormatException. These exceptions occur in situations that the programmer is not usually able to control, depends on the use of the application and maybe only the user of it can do something.

When a checked exception is used, the code must capture it or use throws (there are examples of use and more information in this question) in the method to delegate your capture. Exceptions to Runtime do not need to do this, as the name itself indicates they should not be considered by the compiler. Of course, it is up to the programmer to analyze the situation and decide whether that case should use a checked exception or not, when it is optional. There are cases that even a mistake of Runtime should be required to have some treatment when its flow depends on that correct and something can be better treated.

It is important to point out that the use of these classes is indirect because the ideal is to throw exceptions derived from them and not themselves that are very generic and ideally should even be abstract. One should always launch the more specific possible exceptions.

Exception documentation.

Hierarchy Java Exception

Hierarquia Java Exception

  • Thanks @bigown, your reply helped me understand a little better, what it is, and when to use each one. + 1

4

You asked for didactic examples. What I have is what I have learned from experience.

In the case of checked exceptions I see that it is common for data manipulation libraries to release exceptions related to I/O and Parsing data. Java’s "classical" I/O library for example launches IOException, FileNotFoundException and EOFException, to name the most common. Libraries networking and HTTP communication by also performing I/O launch at least IOException. A JSON parser like json.org that comes along with Android can launch a JSONException related to reading a data from a JSON string, whereas Google’s Gson can launch a JsonSyntaxException.

Anyway, they are situations where the library itself is not prepared to deal with the error and chooses to pass it to a higher level of the call stack or call stack. She does this by declaring that these 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 you are best able to treat, or "recover", from the error that occurred.

By 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 treatment. And it’s typically a "recoverable" error: Your application can prepare for a malformed JSON, a file not found, or an interruption in network communication.

It’s different than a Runtime Exception in the sense that the Runtime typically represents an error in the functioning of the code itself, an error you pick up during execution and need to correct the code and prevent it from happening, as @Maniero said. You need to "shield" your code against it. A parameter that cannot be passed as null otherwise it will launch a IllegalArgumentException or a NullPointerException, a state that theoretically should not happen under pain of launching a IllegalStateException (example: a method that should only be called by the Android UI thread and you involuntarily call from a secondary thread), to name the types that I most use today. When my code makes one of these exceptions, I admit I don’t expect it to happen, but sometimes it does and I know it’s a code defect.

I confess I’ve already treated IOException within a library of mine calling to web services instead of delegating to the user code. I "swallowed" the exception (when very logged) and returned null in my reply. It was a bad design decision. My user code did not know when a null from a successful request or when it came from an I/O error, and are two different situations that require different treatment. It wasn’t my library that needed to handle I/O exceptions but the code that made use of it.

Already in a newer code where I make use of Apache HTTP Client I declared 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 encoding unsupported) and more general I/O. Both are likely to occur during an HTTP request in different situations and I thought it best not to treat them on the same level as they are launched, but to pass them forward, because at this point my code does not know yet what to do with them. If I knew, I could treat them within the method itself executarRequisicaoSincrona instead of declaring them, but that is not the case in my code.

I hope that with these experiences you can have a more accurate notion of when to use or cast exceptions of the two types, checked and unchecked.

Updating: This link explains very well the difference between the two and when to use one or the other (in fact it explains what are the best practices on handling exceptions in Java). I strongly recommend it.

  • Piovezan, very good his analogies to real scenarios, of popular libraries, later I will calmly review his response and @bigown, because they are definitions that should be understood, to use them in the appropriate situations. + 1

  • 1

    Read about some of the reasons for checking and unchecked exceptions: https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.