«« Phone Geeking Include Directory and Threading »»
blog header image
Throws Object

Jim talks about throwing Throwable and using exceptions in private methods. Joshua Bloch covers this pretty well in Effective Java.

Using exceptions when checking parameters is OK. It all depends on the type of error. A programming error, like passing in null when the method doesn't like it, should throw an unchecked (runtime) exception. These types of errors should be noticed immediately by the programmer, and unchecked exceptions do that -- the application quits and a stack trace is printed. IllegalArgumentException is another useful unchecked exception to indicate a programming error.

It is OK in my opinion for private methods to throw exceptions, as long as they are used for exceptional cases, just like public methods. private methods are often refactorings of common code used by many public methods, or just a block of code you want to take out of a public method to simplify it. So they are like extensions to a public method used from the outside. If a private method throws an unchecked exception indicating a programming error then it is like the public method that is using the private method throws that exception, which is just as effective.

On the other side, if I remember correctly another rule of thumb that Effective Java used was if the situation is recoverable you should use a checked exception. For example, if a file isn't found throw FileNotFoundException, catch it and recover. However the code using the method that throws FileNotFoundException shouldn't depend on the exception for it's main flow control. It should look more like:

File f = new File("somefile.png");

if (f.exists() && f.canRead())
{
   try
   {
      //ficticious read that throws IOException
      byte[] buffer = f.read();
   }
   catch (IOException ioe)
   {
      //handle the error gracefully and
      //continue normal program execution
   }
}

The IOException covers an exceptional case here: if the file goes missing or becomes unreadable after the if (...) but before the read(), which could happen in a multithreaded application that uses files a lot or even by another application if a context switch happened there. This kind of race condition would be a real pain in the ass to track down, so exceptions save you from having to synchronize this bit (though you probably should anyway, or lock the file somehow).

But like I said above, it's for exceptional corner cases. You should not be using exceptions for flow control because they are computationally expensive and harder to trace than normal procedural code. Add multithreading into the mix and you can get really whacked in the side of the head.

Throwing and catching Throwable isn't just ugly, it's wrong. The only thing worse is throwing Object (and I've seen that too). The reason you don't want to do this is because you catch unchecked exceptions too, which are programming errors you want to propagate up the stack and be caught by the VM, printed in stack trace and terminate the program immediately. Unchecked exceptions, being the opposite of checked exceptions, indicate that the program is in an unrecoverable state. So it doesn't make much sense to catch unchecked exceptions at all.

Unchecked exceptions in Java are RuntimeException class and its children, which you'll notice extends Object, Thowable and Exception. Code should never explicitly catch Object, Thowable or Exception and if it does it's a dead giveaway that the person who wrote it doesn't have a clue how to program in Java.

There is one slight exception though. Sometimes programs catch all exceptions (including unchecked runtime exceptions) near the top of the stack and log them in a file, especially applications that are GUI-based since it can be hard to see stdout while it's running. This is a good strategy for logging a GUI-based app but it presents it's own problems. What if the log file has an IOException, where is that written to? :)

Posted at February 18, 2004 at 08:34 PM EST
Last updated February 18, 2004 at 08:34 PM EST
Comments
Google
 
Search scope: Web ryanlowe.ca