Re: Why does Java require the throws clause? Good or bad language
design?
Chris Smith wrote:
You aren't making a lot of sense. Given the current language design, I
add a throws clause whenever I want to pass an IOException through a
method. Are you claiming that I could catch and wrap all such
exceptions?
Yes.
If so, then that's why I qualified my statement with
"reasonable quality" code. Reasonable quality code doesn't fight
against the language design; so it doesn't wrap exceptions without
adding levels of abstraction, nor use custom exceptions to express ideas
that are better expressed using exceptions from the core library.
There are perfectly valid engineering reasons for wrapping exceptions and
rethrowing them as custom exceptions, or eating the exception and converting
to a non-exceptional value. It has to do with calling classes not caring any
more what the original exception is, if it was logged at the lowest point, but
only that an application-level exception occurred, or no exception if the
called method ate it.
These are design decisions that are natural to Java usage. There is nothing
"unreasonable" about the quality of these idioms.
Lew:
But from a syntactic and
semantic point of view, it is optional.
Chris Smith:
Again we're back to not particularly meaningful senses of the word
"optional".
It is a design decision to put the throws clause in, which is not required by
the language. That's about as optional as it gets.
The phrase "supposed to do" isn't particularly relevant here.
It's completely relevant. It is the core point. This whole discussion has been
about how to subvert the will of API writers who put checked exceptions in
their method interfaces.
Checked exceptions by design are supposed to force the caller to deal with
them. Complaining about having to deal with them is complaining about them
doing what they're supposed to.
The question under discussion is whether a
different language design could provide the same substantial benefits
with less of the drawbacks.
How would you give the API writer the power to force the calling class to deal
with the range of possible exceptions, at compile time?
I think there have been two ways proposed
that it could: one is the inference of default throws clauses as
discussed here;
Many folks on this thread have explained why this won't work the same way as a
throws clause.
the other (which pre-supposes first-class functions, so
is not really relevant to a Java-like language) is parameterizing the
feature so as to allow exceptions to be propogated from parameters to
their functions.
Interesting, that intrigues me.
People, the throws clause exists to force you to deal with the checked
exceptions. Your complaint is that you are forced to deal with the exceptions
declared in the throws clause.
Well, my complaint in this subthread is that there is no inference
system to prevent me from having to declare them so often.
Not needed. All you have to do is handle the exception at the lower level.
Letting the higher level know that the low level exception was IOException,
for example, is potentially breaking abstraction and encapsulation. There are
sound O-O reasons not to propagate exceptions up the chain always. If you do,
it's a design decision and you signal that by using the throws clause.
If you do not like it, do not blame the language for giving those API
designers too much power.
You are oversimplifying far too much to reasonably discuss the issue.
But the issue is exactly this simple. The whole point of the throws clause is
to give that power.
This kind of "take it or leave it" attitude may be relevant (if a little
rude)
Attitude? Everything I said was objective. It may have been mistaken,
misguided or false, but it was expository. Discuss the points on their merits.
with regards to Java, but it guarantees that you will miss the
point with designing languages.
I am not designing any languages. I am explaining what the throws clause is,
why it's useful, and what it provides, in Java. I am sure that another
language could do without this mechanism, and I do not know enough to know if
the throws clause is a Good Thing, but it has distinct and unique strengths
that are lost by every alternative suggestion presented on this thread so far.
I am not addressing whether those strengths are essential to programming in
general, or whether it is advisable to use checked exceptions. I am only
saying that the throws clause exists for the purpose of forcing exactly that
one must deal with checked exceptions at compile time in a way that guarantees
enforcement. No amount of inference at run time will provide that. In fact,
such run time inference causes clients to break if the API changes what
exceptions it throws between revisions. (This is the risk with unchecked
exceptions.)
Undoubtedly a language that didn't need such compile-time guarantees would not
have a throws clause. That is not Java.
Excoriating practices like rewrapping or eating exceptions is another issue.
You apparently oppose that practice. I aver that it is part of solid,
non-trivial, quality software design, if used in a solid exception-handling
strategy.
- Lew