Re: Why does Java require the throws clause? Good or bad language design?
On Sun, 18 Feb 2007, James Harris wrote:
"James Harris" <james.harri...@googlemail.com> writes:
I have a number of books on Java but none seem to answer the
fundamental question on throws clauses: /why/ force the programmer
to declare what a method /may/ throw?
[...]
My main objections to Java's way is that if aa calls bb calls cc ...
calls zz and I want to handle zz's errors in aa I still have to either
declare them in all intervening modules or catch a generic Exception
superclass and possibly encapsulate them in another object. The latter
is a kludge, IMHO. The former unfortunately obscures the program logic
and intention with foreign constructs or "mechanism."
Leaving aside the whole "does Java suck?" issue, ;) could some
Java expert please comment on the following scenario, which James'
scenario made me think of?
In C++, we can write
void higherLevel(void (*cbf)(int), int arr[], int n) {
for (int i=0; i < n; ++i)
cbf(arr[i]);
}
void callbackFunc(int x) {
if (x == 42)
throw "random exception";
}
void catcher() {
int arr[5] = {1,2,3,42,5};
try {
higherLevel(callbackFunc, arr, 5);
} catch (char *e) {
puts("Exception was thrown:");
puts(e);
}
}
How would the same thing be written in Java? Notice that the
function 'higherLevel' does not know (or need to know) anything
about the exception specification of 'callbackFunc'; I claim that
this is good design, because it means that 'higherLevel' can be
reused in other contexts.
The "contract" here is between 'catcher' and 'callbackFunc';
that is, 'catcher' should catch whatever 'callbackFunc' throws.
But 'higherLevel' is a neutral party in all this; it shouldn't
concern itself with those details.
C++ doesn't let us express that contract very well, unfortunately,
but it does let us write 'higherLevel' without the baggage. Does
Java?
(IIRC, in Java you'd use a bunch of classes or interfaces instead
of bare functions, but I hope you get the idea.)
And a topic for the c.l.misc crowd: What's the Right Way to
handle this scenario? Does C++ really get it right? How do real
functional languages do it?
-Arthur