4 ms·
finally stuff is executed prior to the 'return'; effectively it's placed before the 'return' statement. So it's quite obvious.
by xxs 11mo ago
finally stuff is executed prior to the 'return'; effectively it's placed before the 'return' statement. So it's quite obvious.
- Joker_vD 11mo agoNo, it's not executed before the return, it's executed in the middle of it, so to speak: class Main { static int f() { System.out.println("f()"); return 1; } static int g() { System.out.println("g()"); return 2; } static int h() { try { return f(); } finally { return g(); } } public static void main(String[] args) { System.out.println(h()); } } will print f() g() 2 If "finally" block was executed before the "return" in the "try", the call to f() would not have been made.
- xxs 11mo agoYes, very much is... return is not a single statement or a single opcode. the call to f() is returned on the stack, that's assigned to some local variable via istore, there is no 'ireturn', yet. Then the g() method is called along with whatever is printed, and the next instruction can be ireturn. which would return '2' indeed.
- Joker_vD 11mo ago> return is not a single statement. It is a single statement. It's just that executing it contains of two parts: evaluating the expression, and the non-local transfer of control ― and the weird part is that this control transfer can be hijacked. And it is weird, you can't do this with e.g. "if": if the test condition is evaluated successfully, then the control will go into one of the branches, and you can't mess with that... but with "return", you can abort this transfer of control. Which is, again, weird: all other expression-evaluating statements can go haywire only if the evaluation of the expression inside them throws an exception — but if that doesn't happen, the control transfer is completely trivial, with no special rules about try-catch blocks.
- xxs 11mo agoyou cut the statement in the middle, it's very obviously in terms of bytecode as we talk about bytecode generation.
- Joker_vD 11mo agoMo, we were talking about what would be reasonable semantics for the interaction of two features in a high-level programming language Java; the semantics of bytecode doesn't really matter in this case. The precedent for that would be that "finally"m in fact, really doesn't mesh all that well with what is available for bytecode, so javac has to resort to code duplication.
- deepsun 11mo ago> control transfer can be hijacked. But useful. Similar to Go's "defer".
- Joker_vD 11mo agoGo's "defer" can't prevent return from actually returning from the function. Most of the time, it can't change the computed return value either, unless you go out of your way and use named return values. Go's "defer" also can't do crimes with "break" and "continue". So Go's "defer" has more "and also do some things on the way out" semantics than "you suddenly forget why you were going to leave the kitchen, so you don't".