Home | FAQ | Contact me

Java Exceptions

This is not intended to be exhaustive, but only a 60,000-foot view of this topic.

Broadly, there are two types of exceptions in Java, caught and uncaught, which isn't to say that you can't write code to catch all you can think of. There is a hierarchy at work here and the fork is early. This diagram says a lot:

So-called "caught" exceptions are those that your code should explicitly catch and handle or, at least, throw explicitly and your IDE/compiler will flag methods that fail to react properly. These are innumerable and usually of your making or some library class' making. For example, if something goes wrong when you perform file I/O using java.nio.File.

Uncaught exceptions, on the other hand. are those you don't ordinarily check for or handle. A few examples are shown here. Null-pointer exceptions and illegal argument should simply never happen and are a usually sign that your code is badly written. However, it's sometimes a good idea to expect and catch errors like number-format exceptions in logic where it's likely to happen such as when you try to make an integer of a string of characters:

    int x = Integer.parseInt( "1q234?" );

Default exception handling

In Java, when an exception isn't caught and dealt with, mostly the case of RuntimeExceptions, the application exits unless you've set a default handler to prevent that from happening:

    Thread.setDefaultUncaughtExceptionHandler( some handler );

You may find a framework you're using, such as Tomcat, will have its own default way of handling things and it won't exit, but just log the disaster (in the case of Tomcat, catalina.out) and move on recovering as best it can.

Propagation of exceptions

There are four ways to propagate an exception you've caught:

  1. By method definition (I.e.: throws clause).
  2.  
  3. By rethrowing what was caught.
  4.  
  5. By wrapping what was caught.
    try
    {
        ...
    }
    catch ( IOException e )
    {
        throw new Exception ( "Something else", e );
    }
    

    Below, wrapping is really useful when you can't rethrow the exception because the implementation of the interface doesn't specify the original exception in the contract.

  6. By replacing what was caught with another, different exception. As for #3, but:
        throw new Exception( "Something else ignoring the original", e.getMessage() );
    

    --preserves original exception's message string.