正文
:
6
line
15
:
8
line
9
:
11
line
10
:
13
line
12
:
14
line
13
:
17
line
15
:
19
line
13
:
22
line
14
:
24
line
15
:
25
line
16
:
28
LocalVariableTable:
Start Length Slot Name Signature
3
27
0
t Ljava/lang/
String
;
14
10
1
e Ljava/lang/Exception;
StackMapTable: number_of_entries =
2
frame_type =
255
offset_delta =
13
locals = [
class
java/lang/
String
]
stack = [
class
java/lang/Exception ]
frame_type =
74
stack = [
class
java/lang/Throwable ]
首先看LocalVariableTable信息,这里面定义了两个变量 一个是t String类型,一个是e Exception 类型
接下来看Code部分
第[0-2]行,给第0个变量赋值“”,也就是String t="";
第[3-6]行,也就是执行try语句块 赋值语句 ,也就是 t = "try";
第7行,重点是第7行,把第s对应的值"try"付给第三个变量,但是这里面第三个变量并没有定义,这个比较奇怪
第[8-10] 行,对第0个变量进行赋值操作,也就是t="finally"
第[11-12]行,把第三个变量对应的值返回
通过字节码,我们发现,在try语句的return块中,return 返回的引用变量(t 是引用类型)并不是try语句外定义的引用变量t,而是系统重新定义了一个局部引用t’,这个引用指向了引用t对应的值,也就是try ,即使在finally语句中把引用t指向了值finally,因为return的返回引用已经不是t ,所以引用t的对应的值和try语句中的返回值无关了。
下面在看一个例子:(例2)
1 public class TryCatchFinally {
2
3 @SuppressWarnings("finally")
4 public static final String test() {
5 String t = "";
6
7 try {
8 t = "try";
9 return t;
10 } catch (Exception e) {
11
12 t = "catch";
13 return t;
14 } finally {
15 t = "finally";
16 return t;
17 }
18 }
19
20 public static void main(String[] args) {
21 System.out.print(TryCatchFinally.test());
22 }
23
24 }
这里稍微修改了 第一段代码,只是在finally语句块里面加入了 一个 return t 的表达式。
按照第一段代码的解释,先进行try{}语句,然后在return之前把当前的t的值try保存到一个变量t',然后执行finally语句块,修改了变量t的值,在返回变量t。
这里面有两个return语句,但是程序到底返回的是try 还是 finally。接下来我们还是看字节码信息
public static final java.lang.String test();
Code:
Stack=1, Locals=2, Args_size=0
0: ldc #16