JVM(HotSpot):finally块的相关问题
文章目录
- 前言
- 一、finally 中 return
- 1、代码案例
- 2、字节码
- 二、finally 中修改值
- 1、代码案例
- 2、字节码
- 三、总结
前言
try {}catch (Exception e){}finally {}
如上代码,如果发生异常,我们在可以通过catch
块捕获
捕获后,是打印报错信息还是怎么处理,自行决定
如果捕获后,不打印异常信息,则程序正常运行,就像没有异常
一样。
try {}finally {}
如果,我们去掉catch
块,那么,发生异常,是会打印异常信息的。
但是, 如果finally
中有return
,则不会抛出异常。
一、finally 中 return
1、代码案例
public class TestFinally {public static void main(String[] args) {int getdiv = getdiv(0, 3);System.out.println(getdiv);}public static int getdiv(int a,int b){int j = 0;try {j = b / a;return j;}finally {return 0;}}
}
此时,输出的是0,且没有异常信息。
2、字节码
public static int getdiv(int, int);descriptor: (II)Iflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=5, args_size=20: iconst_01: istore_22: iload_13: iload_04: idiv5: istore_26: iload_27: istore_38: iconst_09: ireturn10: astore 412: iconst_013: ireturnException table:from to target type2 8 10 any10 12 10 any
我们会看到有两个ireturn
,且第8行和第12行时一样的。
说明,jvm
层面,会将finally
中的代码拼接到try和catch块
后面。
这就是为什么输出是0。
二、finally 中修改值
1、代码案例
public class TestFinally {public static void main(String[] args) {int getdiv = getdiv(3, 3);System.out.println(getdiv);}public static int getdiv(int a,int b){int j = 0;try {j = b / a;return j;}finally {j=3;
// return j;}}
}
此时,输出的是1
2、字节码
public static int getdiv(int, int);descriptor: (II)Iflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=5, args_size=20: iconst_01: istore_22: iload_13: iload_04: idiv5: istore_26: iload_27: istore_38: iconst_39: istore_210: iload_311: ireturn12: astore 414: iconst_315: istore_216: aload 418: athrowException table:from to target type2 8 12 any12 14 12 any
会发现,在第一个ireturn
前,重新iload_3
,这就是为什么finally中修改无效的原因。
同时,会看到,18行的athrow,这就说明,发生异常的话,会抛出异常信息。
三、总结
finally中,一定不要写return。,否则程序报错你都发现不了!