您的位置:首页 > 其它

从finally看class编译字节码

2015-10-17 19:33 302 查看
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字节码中没有编译。

待研究!!!!!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: