I just want to add some reasoning for not using checked exceptions at all. This is not a full answer, but I feel it does answer part of your question, and complements many other answers.
Whenever checked exceptions are involved, there's a throws CheckedException somewhere in a method signature (CheckedException could be any checked exception). A signature does NOT throw an Exception, throwing Exceptions is an aspect of implementation. Interfaces, method signatures, parent classes, all these things should NOT depend on their implementations. The usage of checked Exceptions here (actually the fact that you have to declare the throws in the method signature) is binding your higher-level interfaces with your implementations of these interfaces.
Let me show you an example.
Let's have a nice and clean interface like this
public interface IFoo { public void foo(); }
Now we can write many implementations of method foo(), like these
public class Foo implements IFoo { @Override public void foo() { System.out.println("I don't throw and exception"); } }
Class Foo is perfectly fine. Now let's make a first attempt at class Bar
public class Bar implements IFoo { @Override public void foo() { //I'm using InterruptedExcepton because you probably heard about it somewhere. It's a checked exception. Any checked exception will work the same. throw new InterruptedException(); } }
This class Bar won't compile. As InterruptedException is a checked exception, you must either capture it (with a try-catch inside method foo()) or declare that you're throwing it (adding throws InterruptedException to the method signature). As I don't want to capture this exception here (I want it to propagate upwards so I can properly deal with it somewhere else), let's alter the signature.
public class Bar implements IFoo { @Override public void foo() throws InterruptedException { throw new InterruptedException(); } }
This class Bar won't compile either! Bar's method foo() does NOT override IFoo's method foo() since their signatures are different. I could remove the @Override annotation, but I want to program against interface IFoo like IFoo foo; and later on decide on which implementation I want to use, like foo = new Bar();. If Bar's method foo() doesn't override IFoo's method foo, when I do foo.foo(); it won't call Bar's implementation of foo().
To make Bar's public void foo() throws InterruptedException override IFoo's public void foo() I MUST add throws InterruptedException to IFoo's method signature. This, however, will cause problems with my Foo class, since it's foo() method's signature differs from IFoo's method signature. Furthermore, if I added throws InterruptedException to Foo's method foo() I would get another error stating that Foo's method foo() declares that it throws an InterruptedException yet it never throws an InterruptedException.
As you can see (if I did a decent job at explaining this stuff), the fact that I'm throwing a checked exception like InterruptedException is forcing me to tie my interface IFoo to one of it's implementations, which in turn causes havoc on IFoo's other implementations!
This is one big reason why checked exceptions are BAD. In caps.
One solution is to capture the checked exception, wrap it in an unchecked exception and throw the unchecked exception.
DataSeriesclass that holds data which always must remain in time-based order. There is a method to add a newDataPointto the end of aDataSeries. If all of my code is working correctly throughout the project, aDataPointshould never be added to the end which has a prior date to the one already on the end. Every module in the whole project is built with this truism. However, I check this condition and throw an unchecked exception if it happens. Why? If it happens, I want to know who is doing this and fix it.