I quite like checked exceptions. They're actually one of the few things that keeps me writing java for more projects instead of switching more of my time to golang -- golang takes the far opposite approach, and with either returning error codes, or using golang's borderline untyped panic (yes, yes, you can panic typed errors... but it's an incredible PITA to try to construct an error type hierarchy and impossible do terse typed catch blocks with it) doesn't scale well for projects more than about 4ksloc in my experience.
Exceptions signatures, like anything else, need aggressive refactoring to remain a useful part of an API. Always remove throw declarations that aren't needed. Always refactor the exception type hierarchy as your project evolves to keep it sensible.
The worst of typed exceptions I've felt recently is the JGit API (don't get me wrong, JGit is an amazing piece of work; but its sharpest parts are the error handling). There's inchoate masses of IOExceptions from some pieces, JGitAPIExceptions in others, and none of them compose nicely so that when I do large amounts of work I can summarize the error handling up to a few types of conceptually similar problem. And several JGit commands throw checked exceptions for what are essentially fuck-ups in builder patterns, which have been compile-time issues every time I run into them, thus a source of huge irritation (these are prime examples of where you should use unchecked exceptions).
On the other hand, the project I was using that same JGit API in has been one of the best examples of why typed exceptions can be a good idea. This project grew out of a python->java rewrite, and so in the original translation used completely unchecked exceptions as a holdover from the python form. (Why rewrite? It needed to go cross-platform and I needed a stable git api; libgit2 still couldn't clone at the time, so it was jgit or gtfo.) And as I kept working on the project and writing test cases... time and time again, converting things to typed exceptions and refactoring the exception hierarchy paid huge dividends in code quality, huge improvements in API consistency, and raised the quality of tests and final product alike because similar error cases ended up with similar exception types, and tended towards similar handling as I refactored similar exceptions types into one... #wining.
tl;dr being irritated by methods that claim to throw too many exception types is good and healthy. The fix isn't to toss checked exceptions out the window: the fix is to take the pain, and use it to fuel a good API with a tightly controlled and easily understandable set of failure modes.
Exceptions signatures, like anything else, need aggressive refactoring to remain a useful part of an API. Always remove throw declarations that aren't needed. Always refactor the exception type hierarchy as your project evolves to keep it sensible.
The worst of typed exceptions I've felt recently is the JGit API (don't get me wrong, JGit is an amazing piece of work; but its sharpest parts are the error handling). There's inchoate masses of IOExceptions from some pieces, JGitAPIExceptions in others, and none of them compose nicely so that when I do large amounts of work I can summarize the error handling up to a few types of conceptually similar problem. And several JGit commands throw checked exceptions for what are essentially fuck-ups in builder patterns, which have been compile-time issues every time I run into them, thus a source of huge irritation (these are prime examples of where you should use unchecked exceptions).
On the other hand, the project I was using that same JGit API in has been one of the best examples of why typed exceptions can be a good idea. This project grew out of a python->java rewrite, and so in the original translation used completely unchecked exceptions as a holdover from the python form. (Why rewrite? It needed to go cross-platform and I needed a stable git api; libgit2 still couldn't clone at the time, so it was jgit or gtfo.) And as I kept working on the project and writing test cases... time and time again, converting things to typed exceptions and refactoring the exception hierarchy paid huge dividends in code quality, huge improvements in API consistency, and raised the quality of tests and final product alike because similar error cases ended up with similar exception types, and tended towards similar handling as I refactored similar exceptions types into one... #wining.
tl;dr being irritated by methods that claim to throw too many exception types is good and healthy. The fix isn't to toss checked exceptions out the window: the fix is to take the pain, and use it to fuel a good API with a tightly controlled and easily understandable set of failure modes.