I will try to follow the HN ethos and give you the benefit of all the doubt I can. I have to admit, as someone who has been working with this language since the beginning, it's a deeply frustrating struggle. This debate is a microcosm of exactly what went wrong with Java, and why "kids these days" are abandoning it in droves. Have you noticed that all the post-Java languages, from C# to Ceylon, abandon this misfeature?

Point by point:

Unchecked exceptions will blithely and without warning completely explode your stack.

No. They rewind back to the level at which you catch the appropriate exception - possibly Exception. It's true that you aren't always able to catch each exception as specifically as you want. But at least you have a hope of doing that instead of catching RuntimeException and searching back through a dozen nested exceptions, which is today's reality.

In actual practice, there's usually a place you can (and should) catch Exception so that you can log and either retry or abandon the unit of work. In the context of a web server, this is usually "one request". That's why your appserver doesn't crash when something goes wrong.

This isn't theory, your appserver already does this, and it's a wonderful thing. Try doing some node.js programming sometime for a taste of what it's like without that.

Your mistake is believing that there is an alternative to RuntimeException. There is not.

If you pass around an object that conforms to Iterator, but throw an exception within it, __YOU'RE BREAKING THE API CONTRACT.__

Again, your mistake is believing there is an alternative. With the exception of very simple classes, all code has exceptional conditions. Do you create DatabaseIterator which throws DatabaseException (and NetworkException) every time you want to iterate a result set? Then you can't use it with Guava or any of the other 10 million Java libraries that consume standard interfaces, and you might as well not have interfaces at all.

Only pedants care if the compiler checks every single exception. Real-world programmers expect that code will complete normally, and catch exceptions at a high enough level that they can do something useful about it (eg, retry or return an error code to the client).

Exceptional conditions cannot be part of the API contract, because every body of code has different exceptional conditions, and if you try to account for them, you have one of two results:

* You give up on standard interfaces completely. You have DatabaseIterator (which doesn't extend Iterator), FileIterator (which doesn't extend Iterator), etc.

or:

* You throw IteratorException from each method. This is what the Java SDK ends up doing in various places (eg, InvocationTargetException) which is just plain retarded. It would make more sense (and be less annoying) to just throw Exception and leave off the wrapper exception.

You must check the API docs for every line of code you write

Sorry, you are not excused from this, ever. At least with exceptions, you have the option of ignoring the problem at deep levels and catching them higher up - which you already have to do anyways, because nobody wants their app to crash at the first exception. In webapps or appservers it's at the request level; in GUI apps it's usually the UI event handler.

With checked exceptions:

No, the compiler doesn't do any of that shit. Because in the Real World, you end up passing data through a standard interface and the exception gets wrapped. Don't believe me? When was the last time you saw a stacktrace that wasn't wrapped with several Caused by clauses? With the exception of remote API calls (where the exception class may not exist on the client), Caused by: is a fundamental failure of language design. There's no sane reason for this construct to exist. Try writing code in other languages and feel how refreshing it is to get clean stacktraces. You don't even have to leave the JVM, you just have to use any of the languages designed since 1995.