不要在finally代码块中出现return语句

       在项目中绝对不能在finally代码块中出现return语句,这是因为这种处理方式非常容易产生“误解”,会严重误导开发者。例如如下代码:

       对于这段代码,有两个问题:main方法中的doStuff方法的返回值是什么?doStuff方法永远都不会抛出异常吗?

答案是:doStuff(-1)的值是-1,doStuff(100)的值也是-1,调用doStuff方法永远都不会抛出异常,有这么神奇?原因就是我们在finally代码块中加入了return语句,而这会导致出现以下两个问题:

(1)覆盖了try代码块中的return返回值当执行doStuff(-1)时,doStuff方法产生了DataFormatException异常,catch块在捕捉此异常后直接抛出,之后代码执行到finally代码块,就会重置返回值,结果就是-1了,也就是出现了先返回,再执行finally,再重置返回值的情况。

扩展思考:是不是可以定义一个变量,在finally中修改后再return呢?代码如下:

       该方法的返回值永远是1,而不会是-1或0(为什么不会执行到“return 0”呢?原因是finally执行完毕后该方法已经有返回值了,后续代码就不会再执行了),这都是源于异常代码块的处理方式,在代码中加上try代码块就标志着运行时会有一个Throwable线程监视着该方法的运行,若出现异常,则交由异常逻辑处理。

       方法是在栈内存中运行的,并且会按照“先进后出”的原则执行,main方法调用了doStuff方法,则main方法在下层,doStuff在上层,当doStuff方法执行完“return a”时,此方法的返回值已经确定是in类型1(a变量的值,注意基本类型都是值拷贝,而不是引用),此后finally代码块再修改a的值已经与doStuff返回者没有任何关系了,因此该方法永远都会返回1。 

       继续追问:那是不是可以在finally代码块中修改引用类型的属性以达到修改返回值的效果呢?代码如下:

       此方法的返回值永远都是name为李四的Person对象,原因是Person是一个引用对象,在try代码块中的返回值是Person对象的地址,finally中再修改那当然会是李四了。

(2)屏蔽异常

       为什么明明把异常throw出去了,但main方法却捕捉不到呢?这是因为异常线程在监视到有异常发生时,就会登记当前的异常类型为DataFormatException,但是当执行器执行finally代码块时,则会重新为doStuff方法赋值,也就是告诉调用者“该方法执行正确,没有产生异常,返回值是1”,于是乎,异常神奇的消失了,其简化代码如下所示: 

     上面finally代码块中的return已经告诉JVM:doSomething方法正常执行结束,没有异常,所以main方法就不可能获得任何异常信息了。这样的代码会使可读性大大降低,增加了修改的难度。

      在finally中处理return返回值,代码看上去很完美,都符合逻辑,但是执行起来就会产生逻辑错误,最重要的一点是finally是用来做异常的收尾处理的,一旦加上了return语句就会让程序的复杂度徒然提升,而且会产生一些隐蔽性非常高的错误。与return语句相似,System 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你编写这个类。以下是一个示例代码: ```java public class ExceptionHandling { public String tryCatchFinally() { try { // 在try代码块可能会出现异常 int result = 10 / 0; // 这里故意触发一个除零异常 return "Try block executed successfully"; } catch (ArithmeticException e) { // 捕获异常,并返回相应的字符串 return "Exception occurred: " + e.getMessage(); } finally { // 无论try代码块是否出现异常,finally代码块都会执行 // 在finally代码块使用return语句返回不同的字符串 return "Finally block executed"; } } } ``` 在这个示例,我们定义了一个名为`ExceptionHandling`的类,其包含了一个名为`tryCatchFinally`的函数。在这个函数,我们使用了try-catch-finally结构。 在try代码块,我们故意触发了一个除零异常,这会导致程序抛出`ArithmeticException`,并执行catch代码块。catch代码块返回了一个描述异常信息的字符串。 无论try代码块是否出现异常,finally代码块都会执行。在finally代码块,我们使用return语句返回了一个表示finally代码块执行的字符串。 你可以通过调用`tryCatchFinally`方法来观察在try代码块出现异常和没有出现异常时finally代码块的运行情况。例如: ```java public class Main { public static void main(String[] args) { ExceptionHandling exceptionHandling = new ExceptionHandling(); System.out.println(exceptionHandling.tryCatchFinally()); } } ``` 输出结果将会是`Finally block executed`,因为在try代码块出现了异常,但是finally代码块仍然会执行,并且在finally代码块使用return语句返回了对应的字符串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值