-9

Today I wrote some Java which was structured something like this:

if (someCondition) {
    try {
        doSomething();
    } catch (SomeException e) {
        handleException(e);
    }
}

It looked somewhat ugly so I decided to remove excesss {}-block from it.

if (someCondition) try {
    doSomething();
} catch (SomeException e) {
    handleException(e);
}

Which made me think that the try keyword is actually redundant. Isn't catch or finally after {}-block enough to inform the compiler / programmer that exceptions thrown inside the block have special handling?

EDIT: To clarify I don't mean that the whole try block is redundant. Just that the try keyword is. Above example would be written as:

if (someCondition) {
    doSomething();
} catch (SomeException e) {
    handleException(e);
}

EDIT: As requested here is a example method without if:

public void someMethod() {
   {
       doSomething();
   } catch (SomeException ex) {
       handleException(e);
   }
}

Again, clear without the try keyword.

Mika Lammi
  • 1,278
  • 9
  • 21
  • 2
    Why do you think exceptions are only thrown inside blocks? –  Apr 07 '16 at 08:05
  • 1
    The try keyword is used to let the catch block know what is being "tried". {} blocks exist, and they serve an entire different purpose in Java – Stultuske Apr 07 '16 at 08:05
  • @LutzHorn What do you mean? If you catch it you always have a block around it. – Mika Lammi Apr 07 '16 at 08:07
  • @Stultuske Is there a case where compiler could not infer that the block is a try-catch block just from the fact that it is followed by a catch/finally? – Mika Lammi Apr 07 '16 at 08:10
  • 1
    @MikaLammi public void doSomething(){ throw new Exception("no try block here"); } – Stultuske Apr 07 '16 at 08:10
  • 9
    This is a question about the design choices made by James Gosling. We could opine wrt why he made the choices he did, but barring a quote from him, this question cannot be truly *answered*. – T.J. Crowder Apr 07 '16 at 08:10
  • 1
    @Stultuske: That's throwing. Mika's question is about catching. – T.J. Crowder Apr 07 '16 at 08:10
  • @MikaLammi probably, that is possible, then again, it might just as well be an error in coding. – Stultuske Apr 07 '16 at 08:10
  • @Stultuske There is no catch in your example. Please reread the question. – Mika Lammi Apr 07 '16 at 08:11
  • @T.J.Crowder the question, yes, but the calling method will 'catch' it, whether it has a try-catch or not. then, either it propagates, or there is a catch block, or it'll explode in it's face. – Stultuske Apr 07 '16 at 08:12
  • 1
    @MikaLammi I have read it. Just because the keyword catch isn't there, doesn't mean it's not being "caught". – Stultuske Apr 07 '16 at 08:13
  • @Stultuske: The code in your comment doesn't catch the exception. In fact, that code won't compile. – T.J. Crowder Apr 07 '16 at 08:15
  • 4
    Mika - Fundamentally, it would be *possible* to create a parser that does what you describe, but it would be bad on multiple levels: From a parsing perspective, anything that makes you back up is bad (slower). Since not all blocks are `try` blocks, omitting `try` would require backing up when we saw `catch`. From a programming perspective, it would be much harder to read if every block *might* be a `try` or might not, and I have to find the end of the block to find out whether it is. – T.J. Crowder Apr 07 '16 at 08:17
  • @T.J.Crowder change Exception with NullPointerException – Stultuske Apr 07 '16 at 08:18
  • 1
    @Stultuske: Then it would compile. It still doesn't *catch* that exception. The exception exits the method and is either caught by something calling it, or terminates the JVM. – T.J. Crowder Apr 07 '16 at 08:18
  • @T.J.Crowder Backtracking crossed my mind but I don't really think it's the reason in this case. If it would be such a big problem most of us would be using Pascal these days. – Mika Lammi Apr 07 '16 at 09:07
  • @MikaLammi: What features of Java make you think it requires more backtracking in the parser than Pascal? – T.J. Crowder Apr 07 '16 at 09:25
  • @T.J.Crowder Local variables for example. In pascal they are declared at the beginning of the function so the compiler can see right from the start how much stack space needs to be reserved. – Mika Lammi Apr 07 '16 at 09:28
  • @MikaLammi: No backtracking in the parser required for that. – T.J. Crowder Apr 07 '16 at 09:33
  • @T.J.Crowder Maybe not in the parser but I thought it's similar case for the compiler. Not sure if the parser needs a different notion for "just a block" and "try block". I guess it could just have a notion of a generic block that can be followed by catch/finally. Pretty much like "if" can be followed by "else". – Mika Lammi Apr 07 '16 at 09:50
  • @MikaLammi: No, the `if/else` thing is quite different. At the end of the statement attached to an `if`, the parser *expects* either `else` or a new statement. Determining which is which is just single-token look-ahead. – T.J. Crowder Apr 07 '16 at 09:53
  • @T.J.Crowder Sorry but I still don't see it. Similarly at the end of the block the parser expects a `catch`/`finally` or a new statement. Maybe I do some tests later today with [ANTLR](http://www.antlr.org/) to better understand what I am missing. – Mika Lammi Apr 07 '16 at 10:16
  • @MikaLammi: The difference is that it the `else` doesn't change the meaning of the `if` block, it's just something subsequent to it. Your suggestion changes the meaning of the block. Anyway, have fun with it! :-) – T.J. Crowder Apr 07 '16 at 10:23
  • 1
    You are bouncing back and forth between two questions: (a) could one construct a grammar where the `try` keyword could be left out, and (b) would that be a good idea. You are mostly focusing on (a). But (b) is more important -- it goes back to a fundamental design tenet of the Java language -- reading code is more important than writing code. The quest for ultimate concision is usually a "writing" concern, but that's less important than being able to immediately tell what's going on. Many "err on the side of verbosity" decisions stem from this principle. – Brian Goetz Aug 18 '18 at 22:13

2 Answers2

1

As per Java Syntax : catch block should be associated with try block as per java syntax. IF you do not write try and write only catch block then java compiler throws error.

Why is it designed so : why we need to associate every catch/finally block with try is to write exception specific code that should be executed in case of exception in the associated try block.

If java is designed to proceed without try block then programmer does not know what specific code to be written catch block and ends up writing fallback code for all kinds of exceptions in one catch block resulting in execution of all catch block code for any kind of exception.

Also as per your doubt that placement of catch block, if you don't write try then catch block (if designed so by Java designers) has to handle exception generated in the entire code written above it which leads to the scenario explained in the above paragraph.

So, it is better to have code which may generate exception and associate with catch block which can have specific code to handle that exception.It is also the same purpose of writing multiple catch blocks after try block, with most specific or possible exception in first catch block and having the generic catch exception block at the last.

Srikant M
  • 35
  • 2
  • My idea was that you don't need 'try' keyword before the block. 'catch' after any block of code should be sufficient to make it so called 'try-catch block'. – Mika Lammi Jan 30 '18 at 07:15
-1

The Try block lets the catch block now what is going on inside of him .