Re: Why does Java require the throws clause? Good or bad language design?
On Mon, 19 Feb 2007, Michael Rauscher wrote:
Arthur J. O'Dwyer wrote:
In C++, we can write
...
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' ...
The "contract" here is between 'catcher' and 'callbackFunc';
No, there isn't any contract between these two.
catcher calls higherLevel, so one contract is between catcher and
higherLevel.
higherLevel calls cbf, so there's another contract: between
higherLevel and cbf.
FWIW, you're wrong. The "contract" is obviously between the main
function 'catcher' and its helper function 'callbackFunc'. Now, I'll
agree that Java does not let us /express/ that contract; but that's
not the same thing as its not existing in the first place.
Now, let's reformulate your code in Java:
interface CBF {
public void execute(int x);
}
public void higherLevel( CBF cbf, int arr[] ) {
for ( int i = 0; i < arr.length; i++ )
cbf.execute(arr[i]);
}
public void catcher() {
int arr[] = new int[]{1,2,3,42,5};
higherLevel( callBackFunc, arr );
}
There are two things to mention:
1. callBackFunc is not defined, yet.
2. If one looks at CBF one can see the obvious contract that must be
fullfilled when calling or *implementing* CBF#execute:
- the caller must provide one argument of type int.
- execute does not throw a checked exception.
3. 'catcher' doesn't contain a 'catch' clause, which makes its
name misleading at best. ;)
Now, let's implement CBF:
CBF callBankFunc = new CBF() {
public void execute( int x ) {
if ( x == 42 )
throw new Exception();
}
};
This would lead to a compile-time error since the CBF promises that there's
no checked exception when 'execute' gets called.
Okay, so you can't do it that way.
If you really want to throw an exception, there are two ways. Either throw
an unchecked exception
"Unchecked exception" being the Java equivalent of C++'s exceptions,
right? That is, they behave the same way as checked exceptions, but you
don't have to declare them in exception specifications.
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
or if you a checked exception should be thrown,
declare it in CBF#execute's throws-clause.
That would be nice, but you just said that Java won't allow you to
do that. ("This would lead to a compile-time error ...") Unless of
course you propagate the exception specification all the way up into
'higherLevel', which would mean no code reuse in the presence of
checked exceptions.
It sounds like Java indeed has not yet found a magic bullet for
statically analyzing exception-handling. Not that there's anything wrong
with that. But it does mean that the comp.lang.misc discussion, which
is basically a search for a magic bullet, isn't totally pointless. Now
if only I can get the crosspost to c.l.m right this time...
-Arthur