Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is it not possible to insert code between try and catch block?

Tags:

java

try-catch

i was asked a question in interview what happens if we put finally block between try and catch block i answered in that case compiler will think that there is no catch block and it will directly execute finally block. Then he asked why is it not possible to put code between try and catch block?

Can you please help me...

like image 351
Rahul Avatar asked Jul 11 '12 06:07

Rahul


People also ask

Can we write code between try and catch block?

No, we cannot write any statements in between try, catch and finally blocks and these blocks form one unit.

How do you enter a code on catch block?

Java try block is used to enclose the code that might throw an exception. It must be used within the method. If an exception occurs at the particular statement in the try block, the rest of the block code will not execute. So, it is recommended not to keep the code in try block that will not throw an exception.

Can we use try catch and throws together?

Q #2) Can we use throws, try and catch in a single method? Answer: No. You cannot throw the exception and also catch it in the same method. The exception that is declared using throws is to be handled in the calling method that calls the method that has thrown the exception.

Can we write code after finally block?

Actually, it depends on the flow control of the program. That means if the program is written in such a way that if your code is handling the exceptions thrown in the try blocks and if you are handling them in the catch block, then your code after finally block will get executed after the code inside the finally block.


3 Answers

Okay, first thing first - the compiler doesn't execute the code, it just compiles it, allowing it to be run by the JVM.

Empirically speaking, that wouldn't make too much sense, since if you have some code that you would want to put outside the try block but before the catch block, the code could just as well be placed in the try block. The thing is, it would just behave as it were in the try block anyway if you think about it.

Let's assume this is valid Java (this doesn't compile):

try {
    throw new Exception();
}
System.out.println("Sup!");
catch(Exception e) { }

When the exception gets thrown, that line that prints out Sup! will still get skipped as the JVM is searching to jump to the appropriate exception handler to treat Exception. So, in a way, the code behaves just as it would if it were in the try {} block itself, which is why it wouldn't really matter where it is, and the Java specifies that this (now proven useless) construct is illegal.

Now what if that code after the try were to throw another exception itself? If it were valid code, it would behave just like a nested try...catch block in the original try block. Of course that once things start getting complicated, the approach where there is no clear connection between a try and a catch block could get fuzzy, and the JVM would end up not knowing which catch/finally belongs to which try block (especially since the handler doesn't have to be in the same function, or even in the same package!).

like image 141
Andrei Bârsan Avatar answered Oct 13 '22 21:10

Andrei Bârsan


Well, the flippant answer is that the language spec forbids it.

But let's step back a bit and think about it a different way - what if you could do this?

try {
  foo();
}
bar();
catch (Exception e) {
  baz();
}

What could the semantics of this be? If we catch an exception in foo(), is baz() called? What about bar()? If bar() throws, do we catch the exception in that case?

If exceptions in bar() are not caught, and exception in foo() prevent bar() from running, then the construct is equivalent to:

try {
  foo();
} catch (Exception e) {
  baz();
}
bar();

If exceptions in bar() are caught, and exception in foo() prevent bar() from running, then the construct is equivalent to:

try {
  foo();
  bar();
} catch (Exception e) {
  baz();
}

If exceptions in bar() are not caught, and exception in foo() do not prevent bar() from running (bar() is always executed), then the construct is equivalent to:

try {
  foo();
} catch (Exception e) {
  baz();
} finally {
  bar();
}

As you can see, any reasonable semantics for this between-try-catch construct are already expressible without the need for a new - and rather confusing - construct. It's hard to devise a meaning for this construct that is not already redundant.

As an aside, one potential reason we can't do:

try {
  foo();
} finally {
  bar();
} catch (Exception e) {
  baz();
}

could be that it does not reflect actual execution order - catch blocks run before the finally block. This allows catch blocks to make use of resources that the finally block might release later (for example, to request additional diagnostic information from a RPC object or something). Could be made to work the other way as well? Sure. Is it worth it? Probably not.

like image 22
bdonlan Avatar answered Oct 13 '22 23:10

bdonlan


Well it would mean something like this :

try
{
   somCode();
}
someMoreCode();
catch
{
}

What should this mean ? This is not possible because it has no semantic, and therefore it has been decided to be syntaxically incorrect by language designers!

like image 4
Kek Avatar answered Oct 13 '22 21:10

Kek