Why does Java require the throws clause? Good or bad language design?

R

Robbert Haarman

On Thu, Feb 08, 2007 at 03:20:12PM +0000, nukleus wrote:

<insightful comments about using exceptions>

You're right. Exceptions in general, and checked exceptions in
particular, can be very useful and very elegant. I don't think anybody
here doubts that (if so, please post).

However, James's original question was about the trows clause, and the
fact that you have to explicitly list the checked exceptions that a
method throws. In other words, it's not about the utility of exceptions
in general, but about the utility vs. burden of the throws clause.

I particularly dislike the trows clause, and the fact that you have to
add and update throms clauses on all methods that call a certain method,
when these methods are not interested in handling an exceptions
throwable by a "lower" method. However, I am curious what other people,
particularly people who actually _like_ Java, think about the issue.
The extreme case: use the exceptions everywhere,
is simply foolish. First of all, you need to understand
the very nature of exceptions and it is essentially
an equivalent of a goto statement, that totally screws
up your stack and throws your program into place
you could not have imagine.

That's not necessarily true. If I understand correctly, in Java there is
indeed no way to get back to the place an exception was thrown from.
However, it doesn't have to be that way. Common Lisp, for example,
allows the operation that caused the error to be retried (e.g. after
changing some parameters) or to specify a return value to be used
instead of the expression that caused the error, in addition to simply
aborting the operation and transfering control to wherever the exception
handler is.

Regards,

Bob
 
B

buggy

Robbert said:
On Thu, Feb 08, 2007 at 03:20:12PM +0000, nukleus wrote:

<insightful comments about using exceptions>
+1

However, James's original question was about the trows clause, and the
fact that you have to explicitly list the checked exceptions that a
method throws. In other words, it's not about the utility of exceptions
in general, but about the utility vs. burden of the throws clause.

I particularly dislike the trows clause, and the fact that you have to
add and update throms clauses on all methods that call a certain method,
when these methods are not interested in handling an exceptions
throwable by a "lower" method. However, I am curious what other people,
particularly people who actually _like_ Java, think about the issue.

I like the throws clause. Yes when you add a new exception deep within a
call stack, you must then add a throws clause up the chain.

This is a good thing.

By forcing you to add throws clauses, the language forces YOU to
determine where the exception will be handled.

A throws clause tells the compiler that "Yup, it died, but I will not
handle it". So the next method up the call stack is inspected. At some
point there will need to be a catch for that exception. The method
without the throws is the one that will have that catch, enforced by the
compiler.

And if you decide to handle it lower down the chain (via a catch), then
the compiler tells you that your throws is not being thrown. Again, it
forces YOU to re-think your error handling scheme.

I really like when I can get the compiler to locate my mistakes for me :)
 
N

nukleus

I like the throws clause. Yes when you add a new exception deep within a
call stack, you must then add a throws clause up the chain.

This is a good thing.

By forcing you to add throws clauses, the language forces YOU to
determine where the exception will be handled.

A throws clause tells the compiler that "Yup, it died, but I will not
handle it". So the next method up the call stack is inspected. At some
point there will need to be a catch for that exception. The method
without the throws is the one that will have that catch, enforced by the
compiler.

And if you decide to handle it lower down the chain (via a catch), then
the compiler tells you that your throws is not being thrown. Again, it
forces YOU to re-think your error handling scheme.

I really like when I can get the compiler to locate my mistakes for me :)

Yep, and not only mistakes,
but HELP you to pay attention to error conditions.
 
T

Tor Iver Wilhelmsen

James Harris said:
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?

Because it's compiler-enforced documentation. Why do you want to move
stuff from the source to the documentation?
Is there really value in Java's behaviour?

Yes. In the same way there is value in the type safety of a strongly
typed language over an untyped one, for instance.
Or is this an unnecessary burden on the programmer?

For "burden" I read "having to type more than I would in a cryptic
PL/I program". :) Every piece of "simplification" or "syntactic sugar"
means less to type - but more to "not type", ie. having to be aware of
as implicit instead of explicit.

Case in point: Auto-boxing in Java. Earlier you could pinpoint a
NullPointerException to the use of the dot operator on a null
reference in your code (or an explicit throw). No longer! Now you can
also have a NPE when dereferencing an int that really is an Integer,
because of the *implicit* call to Integer.intValue() you did not write
but the compiler added for you.
Why not simply accept exceptions can be thrown which are not listed,
and deal with them in the innermost catch clause which matches?

Because you then just move "this methods throws FooException" from the
code to (hopefully) the documentation. Hint: You want as many
compile-time checks as possible to avoid runtime checks - or errors.
Conversely, if there is a chain of methods: aa calls bb calls cc calls
dd, and dd declares that it throws FileNotFoundException, if we don't
want to handle it in cc do we need to declare that it also throws
FileNotFoundException... and so on through callers to cc etc?

Yes, because you need to document to the users of a method how it
behaves. And throws clauses is compiler-enforced and thus better than
prose.
In terms of code maintenance, if dd could once throw a given
exception but now, because the relevant code has been removed, it
cannot does cc still need to provide for handling the exception
simply /because/ it is listed in dd's throws clause?

Yes.
 
J

James Harris

Because it's compiler-enforced documentation. Why do you want to move
stuff from the source to the documentation?

There have been some excellent replies to my original query (which are
much appreciated). My view now is that enforcing exception checking in
the way that Java does is not desirable. I guess I felt that before
but now have good reasons!

One valid argument for Java's enforcing is that it documents part of
the subprogram's interface. Isn't this, however, ultimately incomplete
as Errors can occur which are undeclared?

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."

It doesn't seem unreasonable to accept that a given subprogram can
generate arbitrary errors. Rather than Java's approach I think I would
rather the language generate the list of possible exceptions after
examining the code and subprograms. This could indeed be part of the
documentation but I don't want to require that each exception be
listed in every module. That seems to be going too far.
Yes. In the same way there is value in the type safety of a strongly
typed language over an untyped one, for instance.

Type safety is valid but the analogy can be taken too far. For
example, Pascal regards the dimensions of an array as part of the
type. Sure, this ties the language down more but is an unnecessary
restriction.

....

This seems a good case in point of why Java's approach is wrong. Maybe
there is a better way.
 
L

Lew

James said:
This seems a good case in point of why Java's approach is wrong. Maybe
there is a better way.

You certainly are entitled to your opinion.

I prefer to take the approach that "Java's approach is what it is", without
"wrong" or "right". Is it a perfect computer language? Is there any such thing?

Java requires that checked exceptions be declared in a method's declaration.
It does not require that any method you write should declare a checked
exception. It is a language feature that you are free not to use.

I agree with you that there are inconveniences to the exception idiom. Calling
such things "wrong" without regard for their purpose is cute but not very
useful. Even if they are "wrong", they exist in Java as they exist in Java.

The only "wrong" thing in Java is that which violates its own definition,
i.e., the JLS. The evaluations we can make as programmers are;

- "I like / dislike that feature", to which I would reply, "Great!"
- "This feature could be expressed in a different language with greater
convenience to the programmer", to which I reply, "You make a very good case."
- "This feature is / is not worth the effort in the particular situation ...",
to which I reply, "That is a very sensible engineering decision."

But "wrong" or "right"? Not engineering evaluations.

For my part, I aver that Java, and in particular its exception idioms, are
very useful in my own work. To which I would expect no more than a general
feeling of comradely satisfaction that someone was getting programming done.

- Lew
 
C

Chris Smith

James Harris said:
There have been some excellent replies to my original query (which are
much appreciated). My view now is that enforcing exception checking in
the way that Java does is not desirable. I guess I felt that before
but now have good reasons!

Whether it's desirable is, I suppose, a matter of who is doing the
desiring. I can attempt to address the other side of the issue, though,
so I will.
One valid argument for Java's enforcing is that it documents part of
the subprogram's interface.

It's not really about documenting. It's about generating knowledge
about your code and providing checks that you have written correct code.
Documentation is, at best, an incidental side-benefit.
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.

I'd disagree with that assessment. It's certainly not a kludge. It may
be a pain at times, but it's exactly what you ought to expect to do.
Failing to throw exceptions that are appropriate for the interface
you're designing is poor abstraction. It is *exactly* like writing a
"lookupEmployee" method in a payroll system that returns a complete
payroll history and expects you to poke around and grab the information
about the employee from that. Both are examples of breaking abstraction
boundaries, and both are poor code.

To understand this bit of language design, you need to get your head
around the fact that declaring methods isn't some boilerplate thing that
you do because the compiler makes you. A method declaration is a
contract with a caller, and the fact that certain errors can be
generated is part of that contract. Another example: suppose that,
early on in the development of some system, you stub out some function.
You know that eventually you'll need to write that method. The throws
clause lets you ensure that the rest of your code properly handles the
error cases that will exist in that method later on. Even though you
have no implementation, you can still write to the contract.
It doesn't seem unreasonable to accept that a given subprogram can
generate arbitrary errors.

If that's true, then you need only throw Exception. There are, of
course, reasons why that is strongly discouraged... but they are EXACTLY
the same reasons that checking exceptions is considered desirable. For
example, I frequently declare main methods of test code with
"throws Exception" tacked onto the end; it makes sense to do so because,
as you said, it's okay for that code to generate arbitrary errors. It's
not generally okay for more significant pieces of software to generate
arbitrary errors; but if it is, then by all means you are free to add
"throws Exception" there, too.
Rather than Java's approach I think I would
rather the language generate the list of possible exceptions after
examining the code and subprograms.

This would, of course, provide none of the main benefit of checked
exceptions, which is the guarantee that error conditions are handled
(even across later changes, for example, for maintenance). The
documentation would just be silently generated and you would have no
idea about the time bomb in your code that's just waiting for someone to
do something wrong.

That being said, though, I think you have a little of a point. It would
make sense to be able to have the compiler infer the throws clause for
certain methods, such as private (perhaps even package protection)
methods in a class. Adding such a thing would certainly encourage more
decomposition of methods, which is a good thing. I'm afraid, though,
that you're proposing that we throw the baby out with the bathwater;
removing checked exceptions for public or protected methods on classes
that are used from outside of their package would be missing out on a
significant advantage of the language.
Type safety is valid but the analogy can be taken too far.

Do you have any basis for this? Lots of people have different tastes
with regard to how much static validation should be performed on code;
but you should at least recognize that you're drawing the line rather
arbitrarily. Have you substantially used languages with much stronger
type systems (say, ML or Haskell)? Do you propose any specific criteria
for making the decision as to whether certain static validation features
are beneficial or not?
Sure, this ties the language down more but is an unnecessary
restriction.

All static validation such as type checking is, by definition,
unnecessary restriction. It is included anyway because it is often
helpful, even if not necessary.
This seems a good case in point of why Java's approach is wrong. Maybe
there is a better way.

Here again, I'd suggest you take the time to look at the throws clause
from a contract standpoint. If code maintenance removed the possibility
of an error at some point, it seems equally likely that further
maintenance would add it back again. It would, in that case, seem like
a very good idea to continue handling potential problems in the code.
On the other hand, if there's some specific reason why it's to be
expected that a certain error will not occur, then you can express that
by removing the exception from the throws clause.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

James said:
One valid argument for Java's enforcing is that it documents part of
the subprogram's interface. Isn't this, however, ultimately incomplete
as Errors can occur which are undeclared?

Not really.

Exceptions are intended to be used for something the
program can handle.

Errors are intended to be used for something the
program can not handle.
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."

I find it very hard to see how it obscures the code to express
its behavior.
It doesn't seem unreasonable to accept that a given subprogram can
generate arbitrary errors.

If that is what you like, then do it.

That programming model is supported by Java. Just let all
your exception extend RuntimeException instead of Exception.
Type safety is valid but the analogy can be taken too far. For
example, Pascal regards the dimensions of an array as part of the
type. Sure, this ties the language down more but is an unnecessary
restriction.

Depends on the level of robustness you need. If an
IndexOutOfBoundsException will cost human lifes, then
maybe a language that does this type of checking
compile time is a good thing.

(today Ada is probably the most widely used language
that really checks that kind of stuff)

Arne
 
L

Lew

Chris said:
To understand this bit of language design, you need to get your head
around the fact that declaring methods isn't some boilerplate thing that
you do because the compiler makes you. A method declaration is a
contract with a caller, and the fact that certain errors can be
generated is part of that contract. ...

Java is one of the languages for those times when static checking and other
"big iron" scaffolding are the order of the day. It is well suited to
"development by contract", a possible term for the methodology Chris described
so eloquently.

It is natural that Java feels a little stuffy at times, but the formality
serves the goals of system robustness, correctness, adaptability and
longevity. I think of Java as "industrial strength", "big bore", perhaps
"armored". These are good things, especially given that Java accomplishes
these things with, all things considered, a reasonably "light" language flavor
overall.

Chris showed how a certain thought process is compatible with what Java offers
for exception declaration semantics. Use these arguably ponderous idioms for
their intended value and you may come to appreciate their solidity.

- Lew
 
A

Arthur J. O'Dwyer

[...]
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);
}

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
 
M

Michael Rauscher

Arthur said:
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'; 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';

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.

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);
}

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.

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.

If you really want to throw an exception, there are two ways. Either
throw an unchecked exception or if you a checked exception should be
thrown, declare it in CBF#execute's throws-clause.

E.g. throw new IllegalArgumentException("Invalid: 42");

Bye
Michael
 
C

Chris Uppal

Chris said:
To understand this bit of language design, you need to get your head
around the fact that declaring methods isn't some boilerplate thing that
you do because the compiler makes you. A method declaration is a
contract with a caller, and the fact that certain errors can be
generated is part of that contract.

But you haven't demonstrated that including a promise of the form "The method
must throw no exceptions except X, Y and Z" is actually adding value to the
contract. I agree that Java /does/ require you to include a clause of that
form in every single method's contract -- the question is whether that's a good
way to write method contracts in general.

-- chris
 
C

Chris Uppal

Lew said:
Calling such things "wrong" without regard for their purpose is cute but
not very useful. Even if they are "wrong", they exist in Java as they
exist in Java.

I think you are missing the OP's point. His interest (as I understand it)
isn't in how to use Java effectively, but in how to design programming
languages. Which is why he asked for our experiences as users of one
experiment in design -- namely checked exceptions in Java.

-- chris
 
C

Chris Smith

Chris Uppal said:
But you haven't demonstrated that including a promise of the form "The method
must throw no exceptions except X, Y and Z" is actually adding value to the
contract.

Indeed, I haven't.

As a step in that direction, I would point out that if one intends to
handle error conditions, then the kinds of error conditions that may
arise IS part of the contract between caller and callee. There should
be no discussion of whether it ought to be, or ought not to be. There
is no other choice; the caller needs to handle those error conditions,
and therefore will have knowledge about what conditions they can be. So
the real questions are: Should that knowledge be statically validated
or should it be the job of human developers to convince themselves that
they've handled all possibilities? If statically validated, is there a
better way of propogating the knowledge so as not to affect intermediate
carriers?

As for the first question, it is not at all clear to me how anyone could
answer it in a general way. Obviously, there are some kinds of problems
for which static validation doesn't carry its weight in syntax and
wordiness, which is why Java has some unchecked exceptions. It is
equally clear to me that there are situations in which it does. IMO,
the important issue is where the line is drawn; and if the line is drawn
too close to one edge -- that "nearly all" or "nearly no" errors should
be statically validated in this way -- whether it's a desirable
simplification to make a universal decision despite knowing that it is
occasionally useful to decide the other way.

I don't have answers to those dillemas. Ultimately they can only be
answered empirically and socially. They are not technical questions. I
argued the other side because, in James' post that I replied to, the
treatment of arguments in favor of static validation was unnecessarily
shallow, and I got the idea that those arguments were not properly
explained. (But I didn't see the thread up to this point, so I could be
wrong.)

As for the second question, I think the answer is yes; there are ways to
improve propogation of error conditions. It ought to be possible for a
function to act as a "carrier" for errors that it does not itself know
about. This is actually a major barrier to numerous styles of code in
Java; but it is solvable without entirely rejecting any static
validation that errors are handled.
 
C

Chris Uppal

Chris said:
As a step in that direction, I would point out that if one intends to
handle error conditions, then the kinds of error conditions that may
arise IS part of the contract between caller and callee.

I agree that there is a contract there (or damn well should be one ;-) But I
don't think it's between the caller and callee -- it seems to me that the
contact (formal or informal) is between the operation, and the handler for any
errors. Java insists on treating every method call as if the caller and callee
were the two principles in that relationship -- and they aren't necessarily,
which is what causes these difficulties.

So
the real questions are: Should that knowledge be statically validated
or should it be the job of human developers to convince themselves that
they've handled all possibilities? If statically validated, is there a
better way of propogating the knowledge so as not to affect intermediate
carriers?

As for the first question, it is not at all clear to me how anyone could
answer it in a general way. Obviously, there are some kinds of problems
for which static validation doesn't carry its weight in syntax and
wordiness, which is why Java has some unchecked exceptions. It is
equally clear to me that there are situations in which it does.

Agreed. In a sense the cases where one /doesn't/ feel the need for static
validation are uninteresting (just don't validate ;-). It's the cases where we
do want validation, but not necessarily as Java provides it, that are
interesting (to me, anyway).

My own suggestion in this area (you'll have to check Google if you're
interested) was a very pragmatic (read: "very hacky") half-way house, in which
the user of an object has some small choice in /what/ contract is statically
enforced. I can't think of anything significantly better in any of the
dimensions of safety, formal soundness, or convenience, which doesn't involve
(potentially) whole-program analysis (which I loath), or load-time/run-time
checks (which I'm quite happy with, but are not every Java programmer's cup of
tea).

As for the second question, I think the answer is yes; there are ways to
improve propogation of error conditions. It ought to be possible for a
function to act as a "carrier" for errors that it does not itself know
about. This is actually a major barrier to numerous styles of code in
Java; but it is solvable without entirely rejecting any static
validation that errors are handled.

<Nods/>

-- chris
 
L

Lew

Michael said:
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.

If you really want to throw an exception, there are two ways. Either
throw an unchecked exception or if you a checked exception should be
thrown, declare it in CBF#execute's throws-clause.

E.g. throw new IllegalArgumentException("Invalid: 42");

Notice that Java supports either style, checked or runtime exceptions,
according to whether the ptrogrammer wishes to make the exception part of the
"contract". It also has a sort of imperfect closure mechanism in the use of
the CBF supertype, which while lacking many features of true closures is
enough for most tasks.

Very nice example.

- Lew
 
R

Robbert Haarman

Not really.

Exceptions are intended to be used for something the
program can handle.

Errors are intended to be used for something the
program can not handle.

This gets to the heart of what I think really is wrong with Java's
exceptions (and, in a wider sense, the whole language). I would say the
exceptions that can or cannot be usefully handled depend on the specific
case. Yet, the list of exceptions that your program must handle (as well
as the list of exceptions it does not have to handle explicitly) has
been hardcoded into the language by the designers, in their wisdom.

I am sure that having the compiler check that certain conditions are
accounted for is a good idea. I am not so sure that hardcoding the
(essentially arbitrary) list of exceptions the compiler will do this
for, and forcing that list on every program, is a good idea.
I find it very hard to see how it obscures the code to express
its behavior.

Certainly, adding code that deals with exceptional situations to the
code that carries out the normal operations obscures those operations.
This is excactly why exceptions are such a good idea: you can have error
checking and handling, without having to litter your code with checks
and error handling code. The more salt the language forces you to add
(which includes not just throws clauses, but also type annotations,
casts, ...), the less clear the function of a snippet of code becomes.
You can argue that you get something in return, but I don't think you
can argue that the function of the code is not obscured.
If that is what you like, then do it.

That programming model is supported by Java. Just let all
your exception extend RuntimeException instead of Exception.

The problem is that neither Java, nor many of its adherents will let you
get away with that. Java won't, because many exceptions are already hard
coded to be checked exceptions. It's adherents won't, because they
consider unchecked exceptions bad style. And they have a point: it's not
the Java Way, and thus, if you are programming in Java, it is not what
you should do.

Regards,

Bob

--
Coal powered the first steam engines, whose killer app was pumping
stagnant water out of coal mines. It powered the railroads, whose killer
app was moving coal.

-- Bruce Sterling
 
R

Robbert Haarman

I think you are missing the OP's point. His interest (as I understand it)
isn't in how to use Java effectively, but in how to design programming
languages. Which is why he asked for our experiences as users of one
experiment in design -- namely checked exceptions in Java.

Actually, not even checked exceptions in general, but, specifically, the
mandatory throws clause (see the subject line). The distinction is
important; checked exceptions can exist without the throws clause.

Regards,

Bob
 
R

Robbert Haarman

It is natural that Java feels a little stuffy at times, but the formality
serves the goals of system robustness, correctness, adaptability and
longevity.

The problem is that Java falls short on multiple counts here, the way I
see it. You get robustness up to unchecked exceptions and casts. You get
correctness as far as Java's type system can express it. I don't agree
with the adaptability at all; if I had to name one language which
encourages "design first, implement later, and don't even think about
changing the design", Java would be it. As for longevity, I have seen
several programs compiled for older versions break on newer versions, so
I cannot really support that either. However, Java was young at the time
I made these observations; it might have matured and stabilized in the
meantime.

Regardless of Java not scoring perfectly with respect to the qualities
you mentioned, it may still be that Java strikes a very good balance
between them. However, I feel that the balance Java strikes is not the
right one for every purpose. In fact, I am convinced that no one balance
would be perfect for all situations. That is why I think Java's real
weakness is not the balance it strikes, but the extent to which that
balance is cast in stone.

In particular, if you want the commonly useful behavior that any
exception should propagate up the call chain until it is handled, and if
it is not handled otherwise, the program should abort with an error
message, you still have to write "throws Exception" and a try ... catch
block (or, alternatively, convert checked exceptions to unchecked
exceptions at some point).

Regards,

Bob
 
L

Lew

Robbert said:
Actually, not even checked exceptions in general, but, specifically, the
mandatory throws clause (see the subject line). The distinction is
important; checked exceptions can exist without the throws clause.

?

The very definition of a "checked" exception is one that must be declared in
the throws clause of the method that throws it.

Consider this quote from
<http://www.developer.com/java/article.php/1455891>:

<quote>
Checked exceptions

All exceptions instantiated from the Exception class, or from subclasses of
Exception other than RuntimeException and its subclasses must either be:

* Handled with a try block followed by a catch block, or
* Declared in a throws clause of any method that can throw them

In other words, checked exceptions cannot be ignored when you write the code
in your methods. According to Flanagan, the exception classes in this
category represent routine abnormal conditions that should be anticipated and
caught to prevent program termination.

Checked by the compiler

Your code must anticipate and either handle or declare checked exceptions.
Otherwise, your program won't compile. (These are exception types that are
checked by the compiler.)
</quote>

For the hard truth, see the JLS, 11.2:
<http://java.sun.com/docs/books/jls/third_edition/html/exceptions.html#44121>

- Lew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top