Checked or unchecked. It is, indeed a perienial topic.
My own opinion is that checked is better, except for two kinds of exceptions: those that can't be expected, and those that could occur just about anywhere. So, for example, ZeroDivisionError could occur just about anywhere in a program that does calculations, so it should be unchecked. ArrayIndexOutOfBoundsException could occur just about anywhere, so it should be unchecked. IOException could occur just when you're doing I/O operations, and I'd make it checked (and so would Gosling apparently). And then there are things like OutOfMemoryError -- there's no way it can be expected, so it is unchecked.
Using this reasoning, most "Business" errors are checked. You suggest that you can "re-throw them or handle them", but doesn't require "try { ... } catch(MyException err) { throw err; }" (which I've seen), just document that it's possible by adding "throws MyException" to the method and do nothing in the code. That minor notation is hardly big overhead. A common exception to this rule is exceptions which SHOULDN'T ever happen -- so, for instance, I never write "// should never get here" in my code; I always write "throw RuntimeException("should never get here");" instead (better to die badly than to keep going with invalid data!).
HOWEVER, having said that, the best gurus I've spoken with tend to, as you've suggested, fall into the unchecked-always camp. See
http://c2.com/cgi/wiki?CheckedExceptionsAreOfDubiousValue for one source. They say that checked exceptions sound great when you're working on a small project, but as soon as things grow to the size of a full-scale project, they start to become a pain. You wind up with a few exceptions that are declared by practically every method as they get passed around. I would say that those ought to be refactored as unchecked when that happens, but I can see their point. So I'm certainly not going to claim that my preferred approach is "best".
-- Michael Chermside