内容简介:java中的很多人都认为运行代码输出 :
java中的 finally
关键字通常与 try/catch
块一起使用。用来在方法结束前或发生异常时做一些资源释放的操作。虽然看起来很简单,在日常开发中也发现几个关于 finlla
问题。
finally 语句块一定会执行吗?
很多人都认为 finally
语句块是肯定要执行的,比如下面的代码,只要进入了 try/catch
块,不管有没有异常,都会执行 finllay
块 :
public static int test(){ try { System.out.println("try block"); int i = 1 / 0; return 0; } finally { System.out.println("finally block"); } }
运行代码输出 :
try block finally block Exception in thread "main" java.lang.ArithmeticException: / by zero
但是回到这个问题,结果并不像大多人所认为的,答案是否定的,我们先来看下面这个例子:
public static int test(){ try { System.out.println("try block"); System.exit(0); return 0; } finally { System.out.println("finally block"); } }
运行代码输出 :
try block
我们在 try
语句块中执行了 System.exit (0)
语句,终止了 Java 虚拟机的运行, finally
语句块还是没有执行。
如果执行了finally,函数返回值问题
public static int test(){ try { System.out.println("try block"); int i = 1 / 0; // 注释 return 0; } catch (Exception e) { System.out.println("catch block"); return 1; } finally { System.out.println("finally block"); return 2; } }
对于上面的代码,相信大部分人都能知道输出值是 2
,打印结果也确实是 2
,就算把 int i = 1 / 0
这一行注释掉,打印结果也是 2
。所以在这里我们可以下结论 : finally
里的 return
语句会把 try/catch
块里的 return
语句效果给覆盖掉。
假如我们不在 finally
中 return
,结果会怎样?我们再看看下面的例子 :
public static int test(){ int i = 999; try { System.out.println("try block"); i = 1 / 0; return i; } catch (Exception e) { System.out.println("catch block"); i = 100; return i; } finally { System.out.println("finally block"); i = 200; } }
打印结果是 :
try block catch block finally block 100
虽然调用了 finllay
改变了i的值,但是最后输出还是 100
,为什么呢?我们可以通过分析字节码文件得到结果 :
public static int test(); Code: 0: sipush 999 3: istore_0 。。。 29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 32: ldc #14 // String catch block 34: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 37: bipush 100 39: istore_0 40: iload_0 41: istore_2 42: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 45: ldc #12 // String finally block 47: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 50: sipush 200 53: istore_0 54: iload_2 55: ireturn 。。。
从字节码文件中可以看出,在 37:39
中把 100
存入 index 0
的位置,就是设置 i
的值为 100
,在 40:41
中把 index 0
的值赋值给了 index 2
的位置,在 50:53
中把 200
存入 index 0
的位置,就是设置 i
的值为 200
,最后在 54:55
中把 index 2
的值加载出来并返回,即最后返回的是 index 2
的值 100
。
对于这种情况我的理解就是在 return
的的时候会把返回值压入栈,并把返回值赋值给栈中的局部变量, 最后把栈顶的变量值作为函数返回值。所以在 finally
中的返回值就会覆盖 try/catch中
的返回值,如果 finally
中不执行 return
语句,在 finally
中修改返回变量的值,不会影响返回结果。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 番外篇2-基本规范、注释、static关键字、import关键字
- 说说iOS中的常用的关键字static ,class(仅限Swift关键字)
- Golang 关键字
- 2019 关键字
- golang关键字
- final关键字深入解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
两周自制脚本语言
[日]千叶 滋 / 陈筱烟 / 人民邮电出版社 / 2014-6 / 59.00元
《两周自制脚本语言》是一本优秀的编译原理入门读物。全书穿插了大量轻松风趣的对话,读者可以随书中的人物一起从最简单的语言解释器开始,逐步添加新功能,最终完成一个支持函数、数组、对象等高级功能的语言编译器。本书与众不同的实现方式不仅大幅简化了语言处理器的复杂度,还有助于拓展读者的视野。 《两周自制脚本语言》适合对编译原理及语言处理器设计有兴趣的读者以及正在学习相关课程的大中专院校学生。同时,已经......一起来看看 《两周自制脚本语言》 这本书的介绍吧!