finally块在代码中什么时候被执行?
在Java语言的异常处理中,finally块的作用十九为了保证无论出现什么情况,finally块里面的代码一定会被执行。由于程序执行return就以为这结束对当前函数的调用并跳出这个函数体,因此任何语句要执行都只能在return执行(除非碰到exit函数),因此,finally块里面的代码也是在return前执行的。此外,如果try-finally或者catch-finally中都有return,那么finally块中的return语句将会覆盖别处的return语句,最终返回调用者那里的是finally中return的值。
public class Main { public static int testFinally(){ try{ return 1; }catch (Exception e){ return 0; }finally { System.out.println("执行Finally"); } } public static void main(String[] args) { int result = testFinally(); System.out.println(result); }}
//执行结果 执行Finally1
再看下面这段程序的执行
public static int testFinally2(){ try{ return 1; }catch (Exception e){ return 0; }finally { System.out.println("执行Finally"); return 3; } } public static void main(String[] args) { int result = testFinally2(); System.out.println(result); }
//结果为执行Finally3
从以上运行的结果可以看出,当finally块中有return语句是,将会覆盖函数中其他的return语句。此外,由于在一个方法内部定义的变量都存储在栈中,当这个函数结束后,其对应的栈就会被收回,此时在其方法体中定义的变量将不存在,因此return在返回是不是直接返回变量的值,而是复制一份,然后返回。因此,对于基本数据类型,在finally块中改变return的值对返回值没有任何影响,而对引用类型的数据会有影响。
public static int testFinally2(){ try{ return 1; }catch (Exception e){ return 0; }finally { System.out.println("执行Finally"); return 3; } } public static int testFinally3(){ int result = 1; try{ result=2; return result; }catch (Exception e){ return 0; }finally { result = 3; System.out.println("执行Finally"); } } public static StringBuffer testFinally4(){ StringBuffer s = new StringBuffer("Hello"); try{ return s; }catch (Exception e){ return null; }finally { s.append(" world!"); System.out.println("执行Finally"); } } public static void main(String[] args) { int result = testFinally3(); System.out.println(result); StringBuffer result2 = testFinally4(); System.out.println(result2); }
//执行结果执行Finally2执行FinallyHello world!
程序在执行到return是会首先将返回值存储在一个指定的位置,其次去执行finally块,最后在返回。以上连个例子说明了执行finally块时,会改变引用类型的变量,而对基础类型没有影响。
还有就是,Java程序中finally块不是一定会运行,若程序在try之前便发生错误,则程序会中断,而不会继续执行。同样,当程序内存在exit函数时,程序也会直接中断,不会继续执行。