| Start |
|---|
| Pitfall - Catching Throwable, Exception, Error or RuntimeException A common thought pattern for inexperienced Java programmers is that exceptions are "a problem" or "a burden" and the best way to deal with this is catch them all1 as soon as possible. This leads to code like this: The above code has a significant flaw. The which is unhelpful and confusing. Worse still, suppose that the it was the "process the input" code that threw the unexpected exception (checked or unchecked!). Now the user will get the misleading message for a problem that didn't occur while opening the file, and may not be related to I/O at all. The root of the problem is that the programmer has coded a handler for
The problem with catching too broad a set of exceptions is that the handler typically cannot handle all of them appropriately. In the case of the In general, the correct solution is to deal with the exceptions that are thrown. For example, you can catch them and handle them in situ: or you can declare them as There are very few situations where catching Here we genuinely want to deal with all exceptions, so catching 1 - Also known as Pokemon Exception Handling (opens new window). |
| Pitfall - Ignoring or squashing exceptions This example is about deliberately ignoring or "squashing" exceptions. Or to be more precise, it is about how to catch and handle an exception in a way that ignores it. However, before we describe how to do this, we should first point out that squashing exceptions is generally not the correct way to deal with them. Exceptions are usually thrown (by something) to notify other parts of the program that some significant (i.e. "exceptional") event has occurred. Generally (though not always) an exception means that something has gone wrong. If you code your program to squash the exception, there is a fair chance that the problem will reappear in another form. To make things worse, when you squash the exception, you are throwing away the information in the exception object and its associated stack trace. That is likely to make it harder to figure out what the original source of the problem was. In practice, exception squashing frequently happens when you use an IDE's auto-correction feature to "fix" a compilation error caused by an unhandled exception. For example, you might see code like this: Clearly, the programmer has accepted the IDE's suggestion to make the compilation error go away, but the suggestion was inappropriate. (If the file open has failed, the program should most likely do something about it. With the above "correction", the program is liable to fail later; e.g. with a Having said that, here is an example of deliberately squashing an exception. (For the purposes of argument, assume that we have determined that an interrupt while showing the selfie is harmless.) The comment tells the reader that we squashed the exception deliberately, and why we did that. Another conventional way to highlight that we are deliberately squashing an exception without saying why is to indicate this with the exception variable's name, like this: Some IDEs (like IntelliJ IDEA) won't display a warning about the empty catch block if the variable name is set to |
| Pitfall - Throwing Throwable, Exception, Error or RuntimeException While catching the The basic problem is that when your application needs to handle exceptions, the presence of the top level exceptions make it hard to discriminate between different error conditions. For example The problem is that because we threw an If the top-level exception is allowed to propagate, we run into other problems:
In short, don't throw these exceptions. Throw a more specific exception that more closely describes the "exceptional event" that has happened. If you need to, define and use a custom exception class. Declaring Throwable or Exception in a method's "throws" is problematic.It is tempting to replace a long list of thrown exceptions in a method's
This advice means that certain other patterns should be avoided. For example: The above attempts to log all exceptions as they pass, without definitively handling them. Unfortunately, prior to Java 7, the |
| Pitfall - Using exceptions for normal flowcontrol There is a mantra that some Java experts are wont to recite: "Exceptions should only be used for exceptional cases." (For example: http://programmers.stackexchange.com/questions/184654 (opens new window) ) The essence of this is that is it is a bad idea (in Java) to use exceptions and exception handling to implement normal flow control. For example, compare these two ways of dealing with a parameter that could be null. In this example, we are (by design) treating the case where The first criterion is readability. While readability is hard to quantify objectively, most programmers would agree that the essential meaning of the first version is easier to discern. Indeed, in order to truly understand the second form, you need to understand that a The second criterion is efficiency. In releases of Java prior to Java 8, the second version is significantly (orders of magnitude) slower than the first version. In particular, the construction of an exception object entails capturing and recording the stackframes, just in case the stacktrace is required. On the other hand, there are many situations where using exceptions is more readable, more efficient and (sometimes) more correct than using conditional code to deal with "exceptional" events. Indeed, there are rare situations where it is necessary to use them for "non-exceptional" events; i.e. events that occur relatively frequently. For the latter, it is worth looking at ways to reduce the overheads of creating exception objects. |
| Pitfall - Catching InterruptedException As already pointed out in other pitfalls, catching all exceptions by using Comes with a lot of different problems. But one perticular problem is that it can lead to deadlocks as it breaks the interrupt system when writing multi-threaded applications. If you start a thread you usually also need to be able to stop it abruptly for various reasons. The But if you have a catch-all expression in your code, the InterruptedException will be caught by it as well and the interruption will not continue. Which in this case could lead to a deadlock as the parent thread waits indefinitely for this thead to stop with So it is better to catch Exceptions individually, but if you insist on using a catch-all, at least catch the InterruptedException individually beforehand. |
| Pitfall - Excessive or inappropriate stacktraces One of the more annoying things that programmers can do is to scatter calls to The problem is that the A better idea is to not call One way to do this is to use a logging framework, and pass the exception object as a parameter of the log event. However, even logging the exception can be harmful if done injudiciously. Consider the following: If the exception is thrown in In short, either log the exception or re-throw it further (possibly wrapped with another exception). Don't do both. |
Pitfall - Directly subclassing Throwable
More to the point there is no practical benefit to directly subclassing |
Read Article
https://develop.horje.com/learn/1434/reference