Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Exceptions: Don't get thrown for a loss

Catch the differences between checked and runtime exceptions

  • Print
  • Feedback

Page 2 of 3

Here's a summary of the mechanical aspects of exceptions:

  • Runtime exceptions:
    • A method signature does not need to declare runtime exceptions
    • A caller to a method that throws a runtime exception is not forced to catch the runtime exception
    • Runtime exceptions extend from RuntimeException or Error
  • Checked exceptions:
    • A method must declare each checked exception it throws
    • A caller to a method that throws a checked exception must either catch the exception or throw the exception itself
    • Checked exceptions extend from Exception


The logic

From a logical viewpoint, checked exceptions and runtime exceptions serve two separate purposes. Checked exceptions indicate an exceptional condition from which a caller can conceivably recover. Conversely, runtime exceptions indicate a programmatic error from which a caller cannot normally recover.

Checked exceptions force you to catch the exception and to do something about it. Take a look at the constructors for java.net.URL. Each constructor may throw a MalformedURLException, an example of a checked exception.

Imagine that you've written a simple program that prompts the user for a URL. Using that URL, the program retrieves a page. If something is wrong with the URL the user enters, the constructor will throw an exception. Since the URL constructor throws a checked exception, the program must catch the exception and try to recover. In the case of the bad URL, the program could ask the user to retype it.

Now, consider the following method:

public void method() {
int [] numbers = { 1, 2, 3 };
int sum = numbers[0] + numbers[3];
}


Executing method() will always yield an ArrayIndexOutOfBoundsException since we are trying to read past the end of the array. Remember, an array index i must be:

0 <= i <= (array.length - 1)


The method caller has no recourse because the caller cannot do anything meaningful in response to the error. This method, as well as method2(), represents a runtime exception example. As I mentioned above, runtime exceptions indicate programmatic errors. Programmatic errors are normally unrecoverable bugs, so the proper recovery is to fix the error in the code.

As a rule of thumb, you should always catch a checked exception once you reach a point where your code can make a meaningful attempt at recovery. However, it is best not to catch runtime exceptions. Instead, you should allow runtime exceptions to bubble up to where you can see them.

If you do catch runtime exceptions, you risk inadvertently hiding an exception you would have otherwise detected and fixed. As a result, catching runtime exceptions complicates unit and regression testing. While testing, seeing a stack trace or allowing the test to catch and report runtime exceptions lets you quickly identify problems. Some programmers advocate catching and logging runtime exceptions, but I disagree because that makes you read through logs while you unit test your code. A unit test should indicate whether the test passed or failed without manual verification from a log. Let the unit test catch the exception, not the code being tested.

  • Print
  • Feedback

Resources