Well, the frivolous answer is that the language specification forbids it.
But let me step back a little and think about it differently - what if you can do it?
try { foo(); } bar(); catch (Exception e) { baz(); }
What could be the semantics of this? If we catch the exception in foo()
, is baz()
called? What about bar()
? If bar()
throws, will we catch an exception in this case?
If the exceptions in bar()
not caught, and the exception in foo()
prevents the execution of bar()
, then the construction is equivalent:
try { foo(); } catch (Exception e) { baz(); } bar();
If the exceptions from bar()
caught, and the exception in foo()
prevents the execution of bar()
, then the construction is equivalent:
try { foo(); bar(); } catch (Exception e) { baz(); }
If exceptions do not fall into bar()
, and an exception to foo()
does not prevent bar()
from executing ( bar()
always executed), then the construction is equivalent:
try { foo(); } catch (Exception e) { baz(); } finally { bar(); }
As you can see, any reasonable semantics for this construct between try-catch are already expressed without the need to create a new - and rather confusing - construct. It is difficult to come up with meaning for this design, which is no longer redundant.
As one of the parties, we cannot make one possible reason:
try { foo(); } finally { bar(); } catch (Exception e) { baz(); }
it may be that it does not reflect the actual order of execution - blocking blocks run before the finally block. This allows catch blocks to use resources that the last block can release later (for example, request additional diagnostic information from an RPC object or something else). Is it possible to make it work like that? Of course. Is it worth it? Probably not.