I'd like to weigh in on this. I have no love for checked exceptions,
the article linked to above makes good points, in particular my pet
hate is the issues around closures and having to wrap all exceptions
with something else. The executor framework in the concurrency
framework uses the ExecutionException for this, you have to access the
cause to find out what happened. Also the verbosity in declaring
catch blocks, variable visibility, all that stuff is cumbersome.
Programmer laziness and incorrect modelling of interfaces also seems
to contribute to the cruft around exceptions, which is a valid reason
to make it simpler.
One area that is very useful for checked exceptions, and also has
relevance to the discussions here about null references, is the use of
checked exceptions to deal with the case where otherwise you would be
returning null eg:
public Object getSomething(String key) throws NoSuchObjectException
This call:
Object o = getSomething("c34d1a")
Might not be able to return a value if the key doesn't exist. If you
have the checked exception, you eliminate the possibility that o can
ever be null, and the return value never needs to be checked. The
exception becomes part of the interface because it relates to the way
the method is satisfied. Any other failure to carry out the request
should be a runtime exception though.
try {
Object o = getSomething("c34d1a")
} catch (NoSuchObjectException e) {
// I don't care, or get something else, or throw a runtime
exception. I'll never get a NPE trying to access o though.
}
I think noops decision to be all unchecked like c# is the right
decision, but the above usage seems to help in the area of null
references, and I believe enhances the ability to write interfaces. Is
there any other way to achieve the same kind of thing without adding
checked exceptions? Using return values to indicate success seems
like a step back. Maybe unchecked exceptions that apply specifically
to returned data or something?
Checked or unchecked, it would be nice to focus on language constructs
that make it easier to add the exception handling down the line
without having to factor in all the new scoping blocks, so that the
code still reads well without being cluttered by the try/catch
construction. A personal hate is refactoring code to add robust
error handling, but having to move variable declarations away from
their assignments out of the try{} scoping blocks, only to find you
did it badly and introduced a bug. Adding the error handling should
be able to leave the working code intact.
Anyway theres about a million posts on this topic on the internet
already, I'll stop now.
On Sep 29, 4:10 am, Alex Eagle <
ea...@post.harvard.edu> wrote:
> Checked exceptions aren't necessarily more correct. They tie an API to the
> particular exceptions thrown by one implementation of the API, or make you
> rethrow a more general exception and you lose "fidelity" - callers up the
> stack can no longer catch the specific exception since they are holding a
> reference to the interface. Misko blogged about that recently:
http://misko.hevery.com/2009/09/16/checked-exceptions-i-love-you-but-...
>
> Unchecked exceptions still appear in the method signature and prompt the
> caller to think about handling them - but you aren't required to have the
> exceptions match the ones thrown by the interface you implement, and the
> caller doesn't need to do anything if they can't handle the exception. It is
> optional to declare them in the method signature, though.
>
> So overall I think we've got this settled, we will encourage listing
> exceptions in a throws clause in the method signature but have no
> requirements about checking them.
>
> Also - I meant to reply to your comment about "@NotNull @Range(1,1000) Int
> foo" - I think the type in this case is not Int but RangedInt - in other
> words, I would like the type system to be able to provide this type without
> needing extra metadata. I'm not sure if that can be extended to something
> like "Email" where you'd need a regex to validate it...
> -Alex
>