15

In java if we have to execute only one statement after if or for the brackets are not necessary. We can write:

if(condition)
  executeSingleStatement();

or

for(init;condition;incr)
  executeSingleStatement();

But in the case of catch block why we can not omit the brackets? Why this is not possible?

catch(Exception e)
   e.printStackTrace();

Because in most of the case we I have only one statement in catch block which is either e.printStackTrace() while testing or logging statement.

Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • a method needs curlies even for a one statement method as well. Perhaps it's because there's an implicit e = thrownException; as the first statement in the catch block. – MeBigFatGuy Jun 22 '11 at 05:23
  • @MeBigFatGuy: What does `e = thrownException;` means? We are declaring `e` as an Exception in the parameter block then why does this statement is needed? – Harry Joy Jun 22 '11 at 05:28
  • @Harry Joy: Think about it. How does 'e' get to contain the exception object? – GKelly Jun 22 '11 at 05:33
  • @Gkelly , @MeBigFatGuy : So it will first initialize `e` with the exception that has occurred and then do the rest processing. Am I right? – Harry Joy Jun 22 '11 at 05:38
  • As a side note: Another interesting case is where you not have any body at all like `if(condition);` (notice the semicolon at the end) – M Platvoet Jun 22 '11 at 06:11
  • *Because in most of the case we have only statement in catch block which is either e.printStackTrace() while testing or logging statement.* I do like being included in the `we` part, poor exception handling is just poor exception handling. – bestsss Jun 25 '11 at 11:46
  • There is a significant difference between a *statement* and a *block*. A statement is simply that -- a sequence of executable operations. A block includes context -- conceptually it is a miniature method body, and can have its own local declarations, etc. This actually is an important distinction for exception handling at several levels. – Hot Licks Mar 12 '13 at 17:44

7 Answers7

10

Find a compiler construction textbook and look-up the dangling-else ambiguity.

Given that in Java, and most other languages with horrible syntax, spacing lies. How do you interpret:

try
try
stuff();
catch (FooException exc)
handle(exc);
catch (BarException exc)
handle(exc);
catch (BazException exc)
handle(exc);

Is it:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    } catch (BarException exc) {
        handle(exc);
    }
} catch (BazException exc) {
    handle(exc);
}

Or:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    }
} catch (BarException exc) {
    handle(exc);
} catch (BazException exc) {
    handle(exc);
}

The dangling-else ambiguity is resolved by associating the else with the inner-most if. Do we want to add a more complicated complication to handle this poor style? No.

Edit: There's a comment that the example does not cover catch. It would be a proper weird decision to require braces on try but not catch/finally. But anyway, for completeness, consider the following code.

try {
stuff();
} catch (FooException foo)
try {
handle(foo);
} catch (BarException bar)
handle(bar);
catch (BazException baz)
handle(baz);
finally
release();

Is the catch of BazException and finally associated with the inner or outer try? Again the language design committee could have added a ton of grammar to disambiguate, but again explicit style wins. My job at Sun/Oracle would have been a little easier if the language had been simplified to mandate explicit braces everywhere.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • 1
    Your answer perfectly explains why we need brackets for try but I am still unclear with the need of brackets with catch statement – Yash Agrawal Aug 11 '17 at 04:04
  • Your explaination uses poor style as a reason, which if it was the actual reason for the language designer they wouldn't have stopped there – Jimmy T. Aug 27 '19 at 17:16
5

I'm not sure why Java doesn't allow that but generally speaking it is better style to use brackets even if there is only one statement. It makes it easier to read and expand.

Here is a related question that addresses whether to use brackets or not: Are curly braces necessary in one-line statements in JavaScript?

Community
  • 1
  • 1
Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26
5

It's not an issue of possible or impossible. It's just a language (syntax) design decision.

There are several implementation of Java language parser. One could modify the parser source less than a day and allow no-bracket-enclosed catch statements.

http://www.google.com/search?q=java+parser

Also note Java language grammar.

9dan
  • 4,222
  • 2
  • 29
  • 44
2

From the Java Language Spec 3.0 - If you look at Chapter 14, it talks about Blocks and Statements. Blocks are identified by { and } and contain many statements. Try/catch/finally are blocks, which per the language spec need to be grouped in { }.

lobster1234
  • 7,679
  • 26
  • 30
  • I think your answer can be elaborated, but your on to something. The same applies for a lot of other commands. For instance, does the class { } require brackets or not (is e.g. "class int no;" also valid?) – Roalt Jun 22 '11 at 05:45
  • 1
    I know that catch requires brackets (as per Java Spec) but I want to know the reason why it is required? – Harry Joy Jun 22 '11 at 07:11
  • 2
    How come this gets +2? You can't explain the rule with the rule itself. – phant0m Jun 22 '11 at 12:09
1

I also do not see any benefit in writing useless code and I also do not understand how more text could be easier.

I help myself by writing one-line-catches in exactly one line:

catch (InvalidArgumentException e) { die (e.getMessage()); }
catch (Exception e)                { die (e); }

For me this is the most readable way. It gets only cluttered when people try to write complete novels into exception names.

catch (CanNotPayAttentionToThatManBehindTheCurtainThrowableRuntimeExceptionWithMessageAndCouseContainItselfAnotherCourseAndMessage e) ...
ceving
  • 21,900
  • 13
  • 104
  • 178
0

I would argue that "in most cases" you should be doing more than just printing or logging the stack trace. This means you are swallowing an exception, which is not generally a good practice. At the least, if you cannot gracefully recover from the exception, you should log and rethrow it in case code higher up the stack can.

That said, I don't think there is really an answer to your question beyond "that's just how they designed it".

mtazva
  • 1,005
  • 9
  • 13
0

Probably inherited from C++. No idea why C++ did that. See my thoughts here: https://stackoverflow.com/questions/6254595/how-do-you-use-the-return/6255489#6255489

It's also worth noting that {} makes grammar simpler, i.e. makes language designer's life easier. The if statement is a good example - the convenience you like does not come cheaply.

Because of the ambiguity like

if(c1) if(c2) A; else B;

interpretation 1 
if(c1)
    if(c2) 
        A;
    else 
        B;

interpretation 2 
if(c1)
    if(c2) 
        A;
else 
    B;

The grammar of if has to be tweaked to resolve the ambiguity. Suppose block is required instead of arbitrary statement, the grammar would be much simpler because of the presence of {}.

So they were probabaly just feeling lazy.

Community
  • 1
  • 1
irreputable
  • 44,725
  • 9
  • 65
  • 93
  • This is not an argument for the programmer, because when the programmer writes down his code the language is already designed, the grammar is already written, and the compiler generator has already done his job. – ceving Mar 12 '13 at 16:48