try-catch-finally | 加上return语句时执行顺序

重要的执行顺序

    • 1. try/catch/finally 介绍
    • 2. try/catch/finally 执行顺序
    • 3. 我们来做道题
      • 再看一个例子
    • 举个例子
    • 4. 最后结论

1. try/catch/finally 介绍

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

  • try必须有
  • finally可以无

总结:

  • try后面必须跟catch 或者 finally 其中之一
  • try后面可以有0个或者多个catch,只能有0个或者1个finally。
  • 若try后面没有catch,则必须有一个finally
    try-catch-finally | 加上return语句时执行顺序_第1张图片

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

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

输出结果:
我是try里面的语句
我是finally里面的执行语句
我是try里的return语句

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语句

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

输出结果:
我是try里面的语句
我是catch语句里面语句1
我是finally里面的执行语句
我是finally里面的return语句

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());
	}

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


  • 答案: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

举个例子

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

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

4. 最后结论

  • 任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
  • 如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,编译器把finally中的return实现为一个warning。但是程序依然会走try/catch里面的retrun语句。

你可能感兴趣的:(JAVA--基础学习,java,jvm,c++,阿里巴巴规范,设计规范)