static int getValue() {
int i = 1;
try {
return i;
} finally {
i++;
}
}
static TT getTT() {
TT t = new TT();
try {
t.i = 1;
return t;
} finally {
t.i++;
}
}
public static void main(String[] args) {
System.out.println(getValue());
System.out.println(getTT().i);
}
}
class TT {
int i;
}
//static int getValue();
// Code:
// 0: iconst_1 //1入操作栈
// 1: istore_0 //1存入索引为0的本地变量栈
// 2: iload_0 //1重新入栈
// 3: istore_2 //通过这句,i的值已经被备份到本地变量区索引为2的slot
// 4: iinc 0, 1 //修改本地变量区索引为0的值做加1操作
// 7: iload_2 //重新将i的值载入操作栈
// 8: ireturn //然后返回栈顶的值,所以返回为1。
// 9: astore_1 //此后的解析,参见另外一个函数
// 10: iinc 0, 1
// 13: aload_1
// 14: athrow
// Exception table:
// from to target type
// 2 4 9 any
static int getValue() {
int i = 1;
try {
return i;
} finally {
i++;
}
}
static TT getTT() {
TT t = new TT(); // 0 new #23 <TT>
// 3 dup
// 4 invokespecial #25 <TT.<init>>
// 7 astore_0
try {
t.i = 1; // 8 aload_0
// 9 iconst_1
//10 putfield #26 <TT.i>
//13 aload_0 // 将t放入操作栈
//14 astore_2 // 将t存到本地变量区索引为2的位置
//15 aload_0 // 将t再次放入操作栈
//16 dup // 复制一份t,放入操作栈
//17 getfield #26 <TT.i> // 取出t.i的值,并放入操作栈
//20 iconst_1 // 将常量1入操作栈
//21 iadd // 将t.i与1相加,结果放入操作栈(原来栈顶的2个操作数出栈
//22 putfield #26 <TT.i> //将栈顶的操作结果赋值回t.i,相当于是t.i = t.i + 1
return t; //25 aload_2 // 将对象引用t放回操作栈
//26 areturn // 将对象引用t返回
} finally { // 如果抛出异常(实际上,t.i = 1是不可能抛出异常的)
t.i++; // astore_1 // 将异常对象(如果上面的代码抛出来的话)存放到本地变量区索引为1的位置
// aload_0 // 将t放入操作栈
// dup // 复制一份t,放入操作栈
// getfield #26 <TT.i> // 取出t.i的值,并放入操作栈
// iconst_1 // 将常量1入操作栈
// iadd // 将t.i与1相加,结果放入操作栈(原来栈顶的2个操作数出栈
// putfield #26 <TT.i> //将栈顶的操作结果赋值回t.i,相当于是t.i = t.i + 1
// aload_1 // 将之前存放在本地变量区索引为1处的 对象引用放入操作栈
// athrow // 将异常对象抛出
// 补充说明:如果出现异常后,虚拟机找到了handler,会把那个出栈的异常引用重新入栈。
}
}
public static void main(String[] args) {
System.out.println(getValue());
System.out.println(getTT().i);
}
}
class TT {
int i;
}