IMO, they're included in Java and C# primarily because they already existed in C++. The real question, then, is why is C++ that way. According to The Design and Evolution of C++ (ยง16.3):
The try
keyword is completely redundant and so are the { }
brackets except where multiple statements are actually used in a try-block or a handler. For example, it would have been trivial to allow:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
However, I found this so difficult to explain that the redundancy was introduced to save support personnel from confused users.
Edit: As to why this would be confusing, I think one has only to look at the incorrect assertions in @Tom Jeffery's answer (and, especially, the number of up-votes it has received) to realize that there would be a problem. To the parser, this is really no different from matching else
s with if
s -- lacking braces to force other grouping, all catch
clauses would match up with the most recent throw
. For those misbegotten languags that include it, finally
clauses would do the same. From the viewpoint of the parser, this is hardly enough different from the current situation to notice -- in particular, as the grammars stand now, there's really nothing to group the catch
clauses together -- the brackets group the statements controlled by the catch
clauses, not the catch clauses themselves.
From the viewpoint of writing a parser, the difference is almost too tiny to notice. If we start with something like this:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
Then the difference would be between:
try_clause: 'try' statement
and:
try_clause: 'try' compound_statement
Likewise, for catch clauses:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
The definition of a complete try/catch block would not need to change at all though. Either way it would be something like:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Here I'm using [whatever]
to indicate something optional, and I'm leaving out the syntax for a finally_clause
since I don't think it has any bearing on the question.]
Even if you don't try to follow all the Yacc-like grammar definition there, the point can be summarized fairly easily: that last statement (starting with try_block
) is the one where catch
clauses get matched up with try
clauses -- and it remains exactly the same whether the braces are required or not.
To reiterate/summarize: the braces group together the statements controlled by the catch
s, but do not group the catch
s themselves. As such, those braces have absolutely no effect upon deciding which catch
goes with which try
. For the parser/compiler the task is equally easy (or difficult) either way. Despite this, @Tom's answer (and the number of up-votes it's received) provides ample demonstration of the fact that such a change would almost certainly confuse users.
Exceptions should be used for exceptional conditions. Throwing an exception is basically making the statement, "I can't handle this condition here; can someone higher up on the call stack catch this for me and handle it?"
Returning a value can be preferable, if it is clear that the caller will take that value and do something meaningful with it. This is especially true if throwing an exception has performance implications, i.e. it may occur in a tight loop.
Throwing an exception takes much longer than returning a value (by at least two orders of magnitude).
Exceptions should never be used to implement program logic. In other words, don't throw an exception to get something done; throw an exception to state that it couldn't be done.
Best Answer
This is sometimes unavoidable, especially if your recovery code might throw an exception.
Not pretty, but sometimes there are no alternatives.