I liked checked exceptions. I just think they were overused. Had a CS prof that summed up the optimal case like this:
Programmer's fault: runtime exception
Not programmer's fault: checked exception
Reading from a file but the disk fails? Not programmer's fault. IOException (checked). Missed a null somewhere? Programmer's fault. NullPointerException (unchecked).
Lack of parametrization meant that any interface that could be implemented in a way that could e.g. throw IOException had to declare it on its methods, even if only a single implementation out of several actually used it. And API clients then had to handle those exceptions even if they knew that they never use the interface implementation that could throw.
Or, alternatively, the interface wouldn't declare it as thrown, and then you couldn't implement it in terms of disk I/O without rewrapping everything into unchecked exceptions. A good example of that is java.util.Map, if you try to implement it on top of a file-based value store.
Programmer's fault: runtime exception
Not programmer's fault: checked exception
Reading from a file but the disk fails? Not programmer's fault. IOException (checked). Missed a null somewhere? Programmer's fault. NullPointerException (unchecked).