Daniel Pitts’ Tech Blog

Please vote no on 8.
Please vote no on 8.

Posts Tagged ‘Esoteric Java Features.’

Exceptional Exceptions!

Monday, July 21st, 2008

First, some boring philosophy about exceptions, then some interesting ways to circumvent the checked exception mechanism.

When designing your system, you should decide carefully which type of exception you want to throw. You have basically three choices: Errors, Exceptions, or RuntimeExceptions.

For unchecked exceptions, generally Errors shouldn’t be thrown directly, and RuntimeExceptions should be thrown (only) if the programmer could have prevented the exception before hand. This last point is arguable, but as a rule of thumb, works pretty well.

Checked exceptions should be used when a condition might occure, outside the programmers control, that isn’t what a typical work-flow would expect.  Check exceptions, if they can’t be dealt with, should bubble up to a user in an appropriate way.  The user should then be given an opportunity to decide what to do, such as retry the operation, report a bug, or go eat lunch and forget about it :-)

Now comes the interesting part. Circumventing checked exceptions.

There are at least two ways to throw a checked exception that isn’t actually checked.  Like with most of my esoteric Java features, they shouldn’t be used in production code. Both are hacks and both are ugly.

The first approach:  Class.newInstance().  Class.newInstance() will propagate any exceptions from the constructor to the calling code.  If your constructor throws a check exception, it will leak from Class.newInstance();

import java.io.IOException;
public class NoChecked1 {
   NoChecked1() throws IOException { throw new IOException("Leaked!"); }
   public static void main(String...args) {
      try {
          NoChecked1.class.newInstance();
      } catch (InstantiationException e) {
      } catch (IllegalAccessException e) {
      }
   }
}

The second approach: Thread.stop(Throwable t). stop(Throwable t) was deprecated a while ago, but Thank God Java Is Backward Compatible. calling this overload of stop will cause the thread to spontaneously throw an exception, checked or otherwise.

import java.io.IOException;
public class NoChecked1 {
   public static void main(String...args) {
      Thread.currentThread().stop(new IOException("Leaked again"));
   }
}

Yikes. Don’t try this at home kids.