论 异常处理机制中的return关键字

Java中,执行try-catch-finally语句需要注意:

第一:return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)

第二:finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的最后。可行的做法有四种:   

  1)return语句只在方法最后出现一次。   

  2)return语句仅在try和catch里面都出现。   

  3)return语句仅在try和方法最后都出现。   

  4)return语句仅在catch和方法的最后都出现。

注意,除此之外的其他做法都是不可行的,编译器会报错。

  (1)如果程序运行到try成功时可以返回结果,则采用方法2。

  (2)如果程序运行到catch时(即中途出错时)无需再继续执行后面的代码了,则采取方法4。

  (3)如果程序运行到try或catch时还需要继续执行后面的代码,则采取方法1。

demo 1:

package cn.day006;

public class Test {

     public static void main(String[] args) {
            System.out.println(getResult());
        }

        @SuppressWarnings("finally")
        public static int getResult(){
            int a =100;
            
            try{
                return a+1; //注意,java的基础数据类型是值传递,这里的返回值已经和上面的a没有关系了
            }catch(Exception e){
                e.printStackTrace();  
            }finally{
                return a;    //最后再把值重定向到a(相当于将try中的返回值覆盖掉),所以输出还是100
            }
        }
}

执行结果:100

demo 2:

package cn.day006;

public class Test {

     public static void main(String[] args) {
            System.out.println(getResult());
        }

        @SuppressWarnings("finally")
        public static int getResult(){
            int a =100;
            
            try{                
                return a++;   //切记 a++   ----> a=a+1 此时a的值做出了改变
            }catch(Exception e){
                e.printStackTrace();  
            }finally{
                return a;   
            }
        }
}

执行结果:101

demo 3:

package cn.day006;

public class Test {

     public static void main(String[] args) {
            System.out.println(getResult());
        }
        public static int getResult(){
            int a =100;            
            try{
                  a++;
                return a;              
            }finally{
                a++;   
            }
        }
}

结果是101。

分析:

在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。

在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,

因此,即使finally中对变量x进行了改变,但是不会影响返回结果。

它应该使用栈保存返回值。

demo 4:

package cn.day006;

public class Test2 {
     public static void main(String[] args) {
            try{
            System.out.println(getResult());
            }catch(Exception e){
                e.printStackTrace();
                System.out.println("截获异常catch");
            }finally{
                System.out.println("异常处理finally");
            }
        }

        @SuppressWarnings("finally")
        public static int getResult() throws Exception{
            int a =100;            
            try{                
                a=a+10; 
                throw new RuntimeException();
            }catch(Exception e){
                System.out.println("截获异常并重新抛出异常");
                throw new Exception();            
            }finally{
                return a;
            }
        }
}

结果如下:

截获异常并重新抛出异常 110 异常处理finally

关键的“截获异常catch”却没有执行!!!

原因是在getResult()的finally中return一个值,等同于告诉编译器该方法没有异常,但实际上异常是有的,这样的结果是该方法的调用者却捕获不到异常,相对于异常被无端的被吃掉了,隐藏杀机啊!!

结论:不要再finally中试图return一个值,这样可能会导致一些意想不到的逻辑错误,finally就是用来释放资源的!!

参考牛人博客:http://blog.csdn.net/z69183787/article/details/61923256

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏余林丰

“不可变的对象”与“不可变的对象引用”

什么是不可变的对象呢?我们都知道String是不可变的,如果有涉及大量的字符串拼接我们最好不要用String,虽然我们在代码中可以这样写: String str...

1939
来自专栏Java开发者杂谈

java finally深入探究

When---什么时候需要finally: 在jdk1.7之前,所有涉及到I/O的相关操作,我们都会用到finally,以保证流在最后的正常关闭。jdk1.7之...

3378
来自专栏Java帮帮-微信公众号-技术文章全总结

【选择题】Java基础测试二(15道)

【选择题】Java基础测试二(15道) 11.对于构造方法,下列叙述正确的是:(AC) A. 构造方法的方法名必须与类名相同; B. 构造方法必须用void...

35310
来自专栏技术碎碎念

python3 入门 (四) 类与继承

Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。...

33812
来自专栏老马说编程

(91) Lambda表达式 / 计算机程序的思维逻辑

在之前的章节中,我们的讨论基本都是基于Java 7的,从本节开始,我们探讨Java 8的一些特性,主要内容包括: 传递行为代码 - Lambda表达式 函数式...

1808
来自专栏令仔很忙

新手学JAVA(七)----Override VS Overload

在同一个类中的许多方法可以拥有相同的名字,只要他们的参数声明不同即可,这种方法被称为重载。 举个例子:

682
来自专栏python学习指南

Scala入门学习笔记三--数组使用

前言 本篇主要讲Scala的Array、BufferArray、List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若...

19610
来自专栏java初学

java — 静态绑定和动态绑定

3318
来自专栏Dato

String、StringBuffer、StringBulider之间的联系和区别

首先,我们大概总体的解释一下这三者的区别和联系 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量...

2618
来自专栏Zephery

2017-03-10学习笔记

1.Integer和int,装箱拆箱 1、基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)...

3538

扫描关注云+社区