finally一定会执行吗?

今天写代码的时候突发奇想,finally一定会执行?于是我就开始了测试,话不多说,上代码

1. 在执行try块之前直接return,发现finally是不会执行的
public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        int i = 11;
        if (i == 11){
            return i;
        }
        try {
            System.out.println("try执行");
        }catch (Exception e){
            System.out.println(e);
        }finally {
            System.out.println("finally执行");
        }
        return 0;
    }

	输出结果:   	 main执行:11
2. 在执行try块之前直接添加一个return语句,直接爆红
public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        return 1/0;
        try {
            System.out.println("try执行");    //出错,原因:无法访问
        }catch (Exception e){
            System.out.println(e);
        }finally {
            System.out.println("finally执行");
        }
        return 0;
    }

那么有人该说了,如果连try块都执行不到,那么finally块肯定不会执行到啊。 话不多说接着上代码

public static void main(String[] args) {
       System.out.println("main执行:"+show01());
   }

   private static int show01() {
       try {
           System.out.println("try执行");    
           
           System.exit(0);  //直接退出虚拟机,谁也救不了
           
       }catch (Exception e){
           System.out.println(e);
       }finally {
           System.out.println("finally执行");
       }
       return 0;
   }
   
   执行结果:  try执行

言归正传:不管是给try块中造了个异常,还是在try块中进行return,finally块还是会执行的

1. 一般情况下:
public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        try {
            System.out.println("try执行");
            return 1;
        }catch (Exception e){
            System.out.println(e);
        }finally {
            System.out.println("finally执行");
        }
        return 0;
    }
    执行结果: try执行								结论:finally块执行在try块的return之前
			  finally执行
			  main执行:1
2. 在try中制造个异常
public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        try {
            System.out.println("try执行");
            return 1/0;
        }catch (Exception e){
            System.out.println("catch执行");
            return 2;
        }finally {
            System.out.println("finally执行");
        }
    }
    执行结果: try执行								结论:跟之前一样finally执行在catch块return的执行前。
			  catch执行
			  finally执行
			  main执行:2

finally块中的返回值:

  1. finally块不含返回值,但是做改变变量值的操作
public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        int i = 0;
        try {
            System.out.println("try执行:"+i);
            return i;
        }catch (Exception e){
            System.out.println("catch执行");
        }finally {
            ++i;
            System.out.println("finally执行:"+i);
        }
        return 0;
    }
    执行结果:	try执行:0
				finally执行:1
				main执行:0

如果看完前面分析,会发现跟想象的不太一样。我们经过前面的分析,finally块的执行时机应该是return之前,那理论上我们应该先++i使得i等于1,在执行return i; 自然会返回1。可是结果却返回了0,这是因为Java程序会把try或者catch块中的返回值保留,也就是暂时的确认了返回值,然后再去执行finally代码块中的语句。等到finally代码块执行完毕后,如果finally块中没有返回值的话,就把之前保留的返回值返回出去。

2. finally中含有返回值:

例1:

public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        try {
            System.out.println("try执行:");
            return 1;
        }catch (Exception e){
            System.out.println("catch执行");
        }finally {
            System.out.println("finally执行:");
            return 2;
        }
    }
    执行结果:	try执行:
				finally执行:
				main执行:2

例2:

public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        int i = 1;
        try {
            System.out.println("try执行:"+i);
            return i;
        }catch (Exception e){
            System.out.println("catch执行");
        }finally {
            i++;
            System.out.println("finally执行:"+i);
            return i;
        }
    }
    执行结果:	try执行:1
				finally执行:2
				main执行:2

例3:

public static void main(String[] args) {
        System.out.println("main执行:"+show01());
    }

    private static int show01() {
        int i = 1;
        try {
            System.out.println("try执行:"+i);
        }catch (Exception e){
            System.out.println("catch执行");
        }finally {
            i++;
            System.out.println("finally执行:"+i);
        }
        return i;
    }
    执行结果:	try执行:1
				finally执行:2
				main执行:2

这三个示例都说明了一点,在分析含有finally块的方法返回值时,要对于return出现的地方进行具体分析。在finally块中进行return操作的话,则方法整体的返回值就是finally块中的return返回值。如果在finally块之后的方法内return,则return的值就是进行完上面的操作后的return值。