By reading the JVM specification, it is learned that the compiler implements the finally statement block through redundancy. We can write a piece of code to do a validation.
JDK Version: 8
As in the following code:
Importjava.io.*; Public class Main { Public Static void Main(string[] args) {Try{foo (); }Catch(IOException e) {intA = -; }Catch(Exception e) {intb = $; }finally{intc = -; } } Public Static void Foo()throwsIOException {}}
Based on the semantics of finally, we can make sure int c = 300
that this line of code is bound to be executed. We can take javap -v Main
a look at the bytecode for this code:
Code:Stack=1, locals=5, args_size=1 0: invokestatic#2 //Method foo: () V 3: Sipush - 6: Istore_17:Goto A Ten: Astore_1 One: Bipush - -: istore_2 -: Sipush - -: Istore_1 -:Goto A +: Astore_1 A: Sipush $ -: istore_2 -: Sipush - in: Istore_1 -:Goto A -: Astore_3 the: Sipush - Panax Notoginseng: istore4 the: Aload_3 +: Athrow A:return
Where the offset is 14, 17, 26, 29, and 34, 37 byte code is int c = 300
the corresponding bytecode. Pushes sipush 300
300 into the operand stack, meaning that the astore_N
top element of the operand stack is saved to the nth slot in the local variable table.
As a result, it is clear that the compiler actually adds the catch
bytecode in the block after each statement block finally
, and try
the end of the block also has int c = 300
the redundancy of the bytecode. If you translate it into Java code, you should:
Public Static void Main(string[] args) {Try{foo ();intc = -;//Redundancy}Catch(IOException e) {intA = -;intc = -;//Redundancy}Catch(Exception e) {intb = $;intc = -;//Redundancy}finally{intc = -; } }
As a result, when we write code, if too much code in the finally block causes the number of bytes to "swell", because the bytecode in finally is "copied" into the try block and all the catch blocks.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Why is the finally statement block bound to be executed in Java?