Monday, November 16, 2009

What to throw, Checked or Unchecked Exceptions?

If you throw a checked exception (and don't catch it), you will need to declare the exception in your method's throws clause. Client programmers who wish to call your method will then need to either catch and handle the exception within the body of their methods, or declare the exception in the throws clause of their methods. Making an exception checked forces client programmers to deal with the possibility that the exception will be thrown.

If you throw an unchecked exception, client programmers can decide whether to catch or disregard the exception, just as with checked exceptions. With an unchecked exception, however, the compiler doesn't force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. Either way, client programmers are less likely to think about what they should do in the event of an unchecked exception than they are in the case of an checked exception.

The simple guideline is:
If you are throwing an exception for an abnormal condition that you feel client programmers should consciously decide how to handle, throw a checked exception.

Note that when String.charAt(int index) receives a bad input, it doesn't throw RuntimeException or even IllegalArgumentException. It throws StringIndexOutOfBoundsException. The type name indicates that the problem was a string index, and the program can query the object to find out what the bad index was.

Here is a collection of the exception guidelines put forth by an article:
  • If your method encounters an abnormal condition that it can't handle, it should throw an exception.
  • Avoid using exceptions to indicate conditions that can reasonably be expected as part of the normal functioning of the method.
  • If your method discovers that the client has breached its contractual obligations (for example, by passing in bad input data), throw an unchecked exception.
  • If your method is unable to fulfill its contract, throw either a checked or unchecked exception.
  • If you are throwing an exception for an abnormal condition that you feel client programmers should consciously decide how to handle, throw a checked exception.
  • Define or choose an already existing exception class for each kind of abnormal condition that may cause your method to throw an exception.
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

Java Checked vs Unchecked Exception

Some guidelines about check and uncheck exception:
  • Only exceptions that will cause a method to complete abruptly should appear in its throws clause.
  • There are two kinds of exceptions in Java, checked and unchecked, and only checked exceptions need appear in throws clauses.
  • Any checked exceptions that may be thrown in a method must either be caught or declared in the method's throws clause.
  • Whether or not an exception is "checked" is determined by its position in the hierarchy of throwable classes.
  • To create a new checked exception, you simply extend another checked exception. All throwables that are subclasses of Exception, but not subclasses of RuntimeException are checked exceptions.
  • Most unchecked throwables declared in java.lang (subclasses of Error and RuntimeException) are problems that would be detected by the Java virtual machine.
  • Errors usually signal abnormal conditions that you wouldn't want a program to handle.
  • If you are throwing an exception to indicate an improper use of your class, you are signalling a software bug. The class of exception you throw probably should descend from RuntimeException, which will make it unchecked. Otherwise, if you are throwing an exception to indicate not a software bug but an abnormal condition that client programmers should deal with every time they use your method, your exception should be checked.
  • At least one clause, either catch or finally, must be associated with each try block. If you have both catch clauses and a finally clause with the same try block, you must put the finally clause after all the catch clauses