• try-catch-finally | 里面有return语句时执行顺序


    1. try/catch/finally 介绍

    try:用来捕获异常
    catch:用于处理try中捕获的异常
    finally:无论是否捕获或处理异常,finally块中的代码都会被执行。

    • try必须有
    • finally可以无

    总结:

    • try后面必须跟catch 或者 finally 其中之一
    • try后面可以有0个或者多个catch,只能有0个或者1个finally。
    • 若try后面没有catch,则必须有一个finally
      在这里插入图片描述

    2. try/catch/finally 执行顺序

    只要try里面出现异常,无论try里是否含return,出现异常下面的程序都不会再执行了;

    情况1:里面均无return语句

    • try里面的代码执行
      若try里面捕获了异常,则执行catch语句;否则不执行catch语句;
    • 1.若有多个catch块,当进入一个catch块,执行完毕后;
      2.即使后面还有catch块,也不会再进入其他catch块。(类似if一样选择了一个catch,其他就会跳过)
      3.如果有finally块,则进入finally块。
    • finally块一定会执行(不论释放出现异常)

    情况2:里面加上return语句

    • finally中无return:当try块中或者catch块中遇到return语句时,先执行完finally里面的代码后,再执行再执行try 或者 catch中的return语句。

      是执行try中的还是catch中的return得看try中是否有异常;
      无异常则不走catch块,有异常则走catch块;

    • 当finally里面有return语句,执行完finally后,直接执行finally里面的return语句,程序结束。(无论try或者catch里面是否有return语句都不会执行)

    我们来举例说明:
    1.try里有异常+finally里面无retun块 :先执行完finally里面的代码后,再执行catch中的return语句。

    public static String testMain() {
            int i = 0;
            String s = null;
            try {
                System.out.println("我是try里面的语句");
    //            i /= 0;
                System.out.println(s.length());//空指针异常
                return "我是try里的return语句";
            } catch (NullPointerException e) {
                System.out.println("我是catch语句里面语句1");
                return "我是catch语句里面的return语句1";
            } catch (Exception e) {
                System.out.println("我是catch语句里面语句2");
                return "我是catch语句里面的return语句2";
            }
            finally {
                System.out.println("我是finally里面的执行语句");
    //            return "我是finally里面的return语句";
            }
        }
     //输出结果:
    //我是try里面的语句
    //我是catch语句里面语句1
    //我是finally里面的执行语句
    //我是catch语句里面的return语句1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.try里无异常+finally里面无retun块 :先执行完finally里面的代码后,再执行try里面的return语句。

    输出结果:
    我是try里面的语句
    我是finally里面的执行语句
    我是try里的return语句
    
    • 1
    • 2
    • 3
    • 4

    3. try里面无异常+finally里有return:执行完finally后,直接执行finally里面的return语句,程序结束

    
    public static String testMain() {
            int i = 0;
            String s = null;
            try {
                System.out.println("我是try里面的语句");
    //            i /= 0;
    //            System.out.println(s.length());//空指针异常
                return "我是try里的return语句";
            } catch (NullPointerException e) {
                System.out.println("我是catch语句里面语句1");
                return "我是catch语句里面的return语句1";
            } catch (Exception e) {
                System.out.println("我是catch语句里面语句2");
                return "我是catch语句里面的return语句2";
            }
            finally {
                System.out.println("我是finally里面的执行语句");
                return "我是finally里面的return语句";
            }
        }
    输出结果:
    //我是try里面的语句
    //我是finally里面的执行语句
    //我是finally里面的return语句
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.try里面有异常 +finally里有return:执行完finally后,直接执行finally里面的return语句,程序结束

    输出结果:
    我是try里面的语句
    我是catch语句里面语句1
    我是finally里面的执行语句
    我是finally里面的return语句
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3. 我们来做道题

    最后程序输出 i=?

    	public int test() {
            int i = 0;
            try {
                i++;
                i = i / 0;
                return i++;
            } catch (Exception e) {
                i++;
                return i++;
            } finally {
                return ++i;
            }
    	 }
    	public static void main(String[] args) {
            System.out.println(test());
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    大家先别看答案自己想想哦


    • 答案:4
      为什么是4呢?我前面不是说直接执行finally里面的return语句吗?
    • 解释:
      原来,我们try / catch里面的return语句不会被输出打印,但是程序还是会走这步的,只不过我们遇到return语句就代表程序结束,所以我们只能最后输出finally块里面的return语句。

    再看一个例子

        public static int testAbc() {
            int i = 0;
            try {
                i++;
                i = i / 0;
    //            return i++;
            } catch (Exception e) {
                i++;
                return i=7;
            } finally {
                return ++i;
            }
        }
        //这个输出的结果就是8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    举个例子

    public static int getInt() {
        int a = 10;
        try {
            System.out.println(a / 0);
            a = 20;
        } catch (ArithmeticException e) {
            a = 30;
            return a;
            /*
             * return a 在程序执行到这一步的时候,这里不是return a 而是 return 30;这个返回路径就形成了
             * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
             * 再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是常量30
             */
        } finally {
            a = 40;
        }
    	return a;
    }
    //输出30
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    public static int getInt() {
        int a = 10;
        try {
            System.out.println(a / 0);
            a = 20;
        } catch (ArithmeticException e) {
            a = 30;
            return a;
        } finally {
            a = 40;
            //如果这样,就又重新形成了一条返回路径,由于只能通过1个return返回,所以这里直接返回40
            return a; 
        }
    }
    //输出40
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. 最后结论

    • 任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
    • 如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,编译器把finally中的return实现为一个warning。但是程序依然会走try/catch里面的retrun语句。
  • 相关阅读:
    对象序列化
    OPENCV--调用GrabCut实现图像分割
    SEAndroid学习
    vue.js事件处理器
    如何写一个全局的 Notice 组件?
    基于小波神经网络的空气质量预测,基于小波神经网络的PM2.5预测,基于ANN的PM2.5预测
    Tcp 协议的接口测试
    TDengine 3.3.0.0 引入图形化管理工具、复合主键等 13 项关键更新
    Vue--Router--解决多路由复用同一组件页面不刷新问题
    拒绝拖延症
  • 原文地址:https://blog.csdn.net/m0_48904153/article/details/126651573