finally源码
public class Test {
public static void main(String[] args) {
System.out.println(new Test().test());
}
int test() {
try {
return func1();
} finally {
return func2();
}
}
int func1() {
System.out.println("func1");
return 1;
}
int func2() {
System.out.println("func2");
return 2;
}
}
编译后字节码
Last modified 2015-10-17; size 901 bytes
MD5 checksum f2beb1a91e4cb99abea1e1f61b1f3176
Compiled from "Test.java"
public class com.lw.loader.Test
SourceFile: "Test.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // com/lw/loader/Test
#2 = Utf8 com/lw/loader/Test
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/lw/loader/Test;
#14 = Utf8 main
#15 = Utf8 ([Ljava/lang/String;)V
#16 = Fieldref #17.#19 // java/lang/System.out:Ljava/io/PrintStream;
#17 = Class #18 // java/lang/System
#18 = Utf8 java/lang/System
#19 = NameAndType #20:#21 // out:Ljava/io/PrintStream;
#20 = Utf8 out
#21 = Utf8 Ljava/io/PrintStream;
#22 = Methodref #1.#9 // com/lw/loader/Test."<init>":()V
#23 = Methodref #1.#24 // com/lw/loader/Test.test:()I
#24 = NameAndType #25:#26 // test:()I
#25 = Utf8 test
#26 = Utf8 ()I
#27 = Methodref #28.#30 // java/io/PrintStream.println:(I)V
#28 = Class #29 // java/io/PrintStream
#29 = Utf8 java/io/PrintStream
#30 = NameAndType #31:#32 // println:(I)V
#31 = Utf8 println
#32 = Utf8 (I)V
#33 = Utf8 args
#34 = Utf8 [Ljava/lang/String;
#35 = Methodref #1.#36 // com/lw/loader/Test.func1:()I
#36 = NameAndType #37:#26 // func1:()I
#37 = Utf8 func1
#38 = Methodref #1.#39 // com/lw/loader/Test.func2:()I
#39 = NameAndType #40:#26 // func2:()I
#40 = Utf8 func2
#41 = Utf8 StackMapTable
#42 = Class #43 // java/lang/Throwable
#43 = Utf8 java/lang/Throwable
#44 = String #37 // func1
#45 = Methodref #28.#46 // java/io/PrintStream.println:(Ljava/lang/String;)V
#46 = NameAndType #31:#47 // println:(Ljava/lang/String;)V
#47 = Utf8 (Ljava/lang/String;)V
#48 = String #40 // func2
#49 = Utf8 SourceFile
#50 = Utf8 Test.java
{
public com.lw.loader.Test();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/lw/loader/Test;
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #1 // class com/lw/loader/Test
6: dup
7: invokespecial #22 // Method "<init>":()V
10: invokevirtual #23 // Method test:()I
13: invokevirtual #27 // Method java/io/PrintStream.println:(I)V
16: return
LineNumberTable:
line 5: 0
line 7: 16
LocalVariableTable:
Start Length Slot Name Signature
0 17 0 args [Ljava/lang/String;
int test();
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokevirtual #35 // Method func1:()I
4: pop
5: goto 9
8: pop
9: aload_0
10: invokevirtual #38 // Method func2:()I
13: ireturn
Exception table:
from to target type
0 8 8 any
LineNumberTable:
line 11: 0
line 12: 8
line 13: 9
LocalVariableTable:
Start Length Slot Name Signature
0 14 0 this Lcom/lw/loader/Test;
StackMapTable: number_of_entries = 2
frame_type = 72 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 0 /* same */
int func1();
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #44 // String func1
5: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: iconst_1
9: ireturn
LineNumberTable:
line 18: 0
line 19: 8
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/lw/loader/Test;
int func2();
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #48 // String func2
5: invokevirtual #45 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: iconst_2
9: ireturn
LineNumberTable:
line 23: 0
line 24: 8
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/lw/loader/Test;
}
public class TestRef {
public static void main(String[] args) {
System.out.println(new TestRef().test());
}
TestP test() {
try {
return func1();
} catch (Exception e) {
return new TestP();
} finally {
// return
func2();
}
}
TestP func1() {
System.out.println("func1");
return new TestA();
}
TestP func2() {
System.out.println("func2");
return new TestB();
}
}
com.lw.loader.TestP test();
flags:
Code:
stack=2, locals=4, args_size=1
0: aload_0
1: invokevirtual #35 // Method func1:()Lcom/lw/loader/TestP;
4: astore_3
5: aload_0
6: invokevirtual #38 // Method func2:()Lcom/lw/loader/TestP;
9: pop
10: aload_3
11: areturn
12: astore_1
13: new #41 // class com/lw/loader/TestP
16: dup
17: invokespecial #43 // Method com/lw/loader/TestP."<init>":()V
20: astore_3
21: aload_0
22: invokevirtual #38 // Method func2:()Lcom/lw/loader/TestP;
25: pop
26: aload_3
27: areturn
28: astore_2
29: aload_0
30: invokevirtual #38 // Method func2:()Lcom/lw/loader/TestP;
33: pop
34: aload_2
35: athrow
Exception table:
from to target type
0 5 12 Class java/lang/Exception
0 5 28 any
12 21 28 any
LineNumberTable:
简单看过代码就能知道执行流程,但是从字节码中能让我们对执行流程有更深刻的理解。
《深入理解java虚拟机》有相似代码对正常、异常、finally代码流程进行讲解,唯一困惑的是正常流程中的return字节码中没有编译。
待研究!!!!!!!!!!