Bootstrap

try、catch中finally和return执行顺序以及finally对变量操作对变量和结果的影响

前言:

Java通过API中的Throwable类的众多子类描述各种不同的异常,所以java异常是Throwable子类的实例化对象。Throwable有两个重要的子类:Exception和Error。

Error

Error错误代表了程序运行时Java系统内部的错误,与程序设计者的操作无关。 Error是不可查的 。

Exception

是程序本身可以处理的异常,程序设计者应尽量加以处理的部分。

Exception分为两类,一类是:运行时异常(RuntimeException)另一类是编译时异常(书上写的可称非运行时异常或已检查异常,是因为在Exception类中的子类只有RuntimeException是运行时异常。)

RuntimeException也是不可查异常。

  • 常见的运行时异常(虽然编译也能通过,但是还是需要我们处理避免出现这些异常。)
ArrayIndexoutofBoundsException访问数组时使用无效索引值
NullPointException尝试访问null对象成员,空指针异常
ClassCastException类型转换异常
ArithmeticException非法的算术运算,如以0作除数
NumberFormatException数字转化格式异常
IllegalArgumentException方法接收到非法参数

try - catch -finally的学习
一般例子为:

try {
    //可能出现异常的代码
}catch(异常类型1 变量名1) {
    //处理异常的方式1
}catch(异常类型2 变量名2) {
    //处理异常的方式2
}
....
finally {
    //一定会执行的代码
}
1.执行try(catch)中的return,看看finally的顺序
 public static int Sum() {
        int num;//这里把num的定义写在了try和finally的外部,num指向的就是一个了。
        try {
            num = 10;
            System.out.println(num);
            num = 30;
            return num;
        } finally {
             num = 20;
            System.out.println("finally的num:"+num);
        }
    }
     public static void main(String[] args) {
        
        System.out.println(Sum());
        
    }

输出为:

10
finally的num:20
30

通过上面两个例子可以了解到:try ,finally 语句是顺序执行的,不过try块区域的return是最后再return输出的。也就是会执行完Finally再return。

2.执行try(catch)中的return 且 return为方法,看看finally的顺序
 //写一个含try和finally的方法类型为String(为了后续输出对应。)
    public static String Fun() {
        try {
            System.out.println("try");//----------1
            return FunctionM();//进入这个方法中。
        } finally {
            System.out.println("finally");//-------------4
        }
    }
	//用try来调用FunctionM方法看输出顺序如何?
    public static String FunctionM() {
        System.out.println("FunctionM方法中的输出语句。");//--------2
        System.out.println(FunctionN("成功在return “pz” 前输出"));//----------3
        //顺序执行。
        return FunctionN("pz");//-------------5
    }
	//通过上一步方法来继续return一个方法,进一步测试输出顺序。
    public static String FunctionN(String name) {
        return name;
    }

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

输出为:

try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
pz

可以发现,语句是按顺序执行,如果遇到了return,会进去执行其中的方法语句,执行到遇到return为止。然后跳到finally语句中输出,再return最后调用得到的数据。(如果return为方法的话)。

3.执行try(catch),如果在finally语句中添加一个return语句的话。
public static String Fun() {
        try {
            System.out.println("try");
            return FunctionM();
        } finally {
            System.out.println("finally");
            return "lxm";
            //区别就是这里加上了一句return。
        }
    }

    public static String FunctionM() {
        System.out.println("FunctionM方法中的输出语句。");
        System.out.println(FunctionN("成功在return “pz” 前输出"));
        return FunctionN("pz");
    }

    public static String FunctionN(String name) {
        return name;
    }

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

输出为:

try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
lxm

结论:当finally有返回值时,会直接返回。不会返回try或catch中的返回值或返回方法的返回值。

4.当finally对变量做修改是否影响返回值
public static int show() {
        int a = 10;
        try {
            System.out.println(a + " 我是try");
            return a;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.println("finally模块被执行");
            a = 0;
            System.out.println(a);
        }
    }
 
    public static void main(String args[]) {
        System.out.println("main:"+show());
    }

输出为:

10 我是try
finally模块被执行
0
main:10

结论:try或catch的return是一个变量,函数的是从两个之中返回时,后面finally中语句有对返回的变量进行赋值的操作时,不会影响返回的值,可以认为返回的值延迟到FINALLY执行后再返回。

5.当finally对变量做修改不影响返回值,但是否影响变量的值
public class Demo{

    static int num;

    public static int Sum() {
       //这里把num的定义写在了try和finally的外部,num指向的就是一个了。
        try {
            num = 10;
            System.out.println(num);
            num = 30;
            return num;
        }catch (Exception e) {
            e.printStackTrace();
            num = 222;
            return num;
        }finally {
            num = 20;
            System.out.println("finally的num:"+num);
        }
    }

    public static void main(String[] args) {
        System.out.println("main:"+Sum());
        System.out.println("Demo.num"+Demo.num);
    }

}

输出为:

10
finally的num:20
main:30
Demo.num20

结论:try或catch的return是一个变量,函数的是从两个之中返回时,后面finally中语句有对返回的变量进行赋值的操作时,不会影响返回的值,但是会影响静态变量num,也就是会影响变量num。假如一些输入流输出流,可以在finally区域块把它们close,因为finally会影响最终的变量,但是不影响try(catch)返回结果,可以说try,catch结果的return虽然在finally后面执行,但是该结果的值要返回的值已经在finally执行前保存到内存,等到执行完finally后,再执行返回保存在内存的值(不受finally影响)。

;