Java学习手册:finally块中的代码什么时候被执行?

版权声明:本文为博主原创文章,未经博主允许不得转载,转载请务必注明出处: https://blog.csdn.net/MaybeForever/article/details/88982415

一、finally块中的代码什么时候被执行?

在Java语言的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定被执行。由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,因此任何语句要执行都只能在return前执行(除非碰到exit函数),因此finally块中的代码也是在return前执行的。此外,如果try-finally或者catch-finally中都有return,那么finally块中的return语句将会覆盖别处的return语句,最终返回调用者那里的是finally中return的值。

//Demo1:在执行return语句前先执行finally块中的代码
package com.haobi;

public class Test1 {
	public static int testFinally(){
		try {
			return 1;
		} catch (Exception e) {
			return 2;
		}finally {
			System.out.println("execute finally");
		}
	}
	
	public static void main(String[] args) {
		int result = testFinally();
		System.out.println(result);
	}
}
//程序输出结果如下:
execute finally
1

//Demo2:当finally块中有return语句时,将会覆盖函数中其他return语句
package com.haobi;

public class Test2 {
	public static int testFinally(){
		try {
			return 1;
		} catch (Exception e) {
			return 2;
		}finally {
			System.out.println("execute finally");
			return 3;
		}
	}
	
	public static void main(String[] args) {
		int result = testFinally();
		System.out.println(result);
	}
}
//程序输出结果如下:
execute finally
3

由于在一个方法内部定义的变量都存储在栈中,当这个函数结束后,其对应的栈就会被回收,此时在其方法体中定义的变量将不存在了,因此return在返回时不是直接返回变量的值,而是复制一份,然后返回。因此,对于基本类型的数据,在finally块中改变return的值对返回值没有任何影响。如下例所示:

//Demo3:
package com.haobi;

public class Test3 {
	public static int testFinally1(){
		int result = 1;
		try {
			result = 2;
			return result;
		} catch (Exception e) {
			return 0;
		}finally {
			result = 3;
			System.out.println("execute finally1");
		}
	}
	
	public static StringBuffer testFinally2(){
		StringBuffer s = new StringBuffer("Hello");
		try {
			return s;
		} catch (Exception e) {
			return null;
		}finally {
			s.append(" World!");
			System.out.println("execute finally2");
		}
	}
	
	public static void main(String[] args) {
		int res1 = testFinally1();
		System.out.println(res1);
		StringBuffer res2 = testFinally2();
		System.out.println(res2);
	}
}
//程序输出结果如下:
execute finally1
2
execute finally2
Hello World!

程序在执行return语句时会首先将返回值存储在一个指定的位置,其次去执行finally块,最好再返回。上述程序中:在方法testFinally1中调用return前,先把result的值2存储在一个指定的位置,然后再去执行finally块中的代码,此时修改result的值将不会影响到程序的返回结果。testFinally2中,在调用return前首先把s存储到一个指定的位置,由于s为引用类型,因此在finally块中修改s将会修改程序的返回结果。

二、出现在Java程序中的finally块是不是一定会被执行?

答案:不一定会被执行。下面给出两个finally代码块不会被执行的例子。
(1)当程序在进入try语句之前就出现异常时,会直接结束,不会执行finally块中的代码,示例如下:

package com.haobi;

public class Test4 {
	
	public static void testFinally() {
		int i = 5/0;
		try {
			System.out.println("try block");
		} catch (Exception e) {
			System.out.println("catch block");
		}finally {
			System.out.println("fianlly block");
		}
	}
	
	public static void main(String[] args) {
		testFinally();
	}
}
//程序输出结果如下:
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.haobi.Test4.testFinally(Test4.java:6)
	at com.haobi.Test4.main(Test4.java:17)

程序在执行int i=5/0时会抛出与异常,导致没有执行try块,因此finally块也就不会被执行。
(2)当程序在try块中强制退出时也不会去执行finally块中的代码,示例如下:

package com.haobi;

public class Test5 {
	
	public static void testFinally() {
		try {
			System.out.println("try block");
			System.exit(0);
		} catch (Exception e) {
			System.out.println("catch block");
		}finally {
			System.out.println("fianlly block");
		}
	}
	
	public static void main(String[] args) {
		testFinally();
	}
}
//程序运行结果如下:
try block

上例在try块中通过调用System.exit(0)强制退出了程序,因此导致finally块中的代码没有被执行。

猜你喜欢

转载自blog.csdn.net/MaybeForever/article/details/88982415