public class FinallyTest { public static void main(String[] args) { System.out.println("test1:" + testFinal1()); System.out.println("test2:" + testFinal2()); System.out.println("test3:" + testFinal3()); System.out.println("test4:" + testFinal4()); } static int testFinal1() { int i = 1; try { return i; } finally { System.out.println("in testFinal1():finally 肯定会被执行的!"); i = 48; } } static String testFinal2() { String str = "try"; try { return str; } finally { System.out.println("in testFinal2():finally 肯定会被执行的!"); str = "finally"; } } static StringBuilder testFinal3() { StringBuilder build = new StringBuilder("try "); try { return build; } finally { System.out.println("in testFinal3():finally 肯定会被执行的!"); build.append("finally"); build = new StringBuilder("你猜我是谁!"); } } @SuppressWarnings("all") static String testFinal4() { try { return "return in try"; } finally { System.out.println("in testFinal4():finally 肯定会被执行的!"); return "return in finally"; } } }
输出为:
in testFinal1():finally 肯定会被执行的!
test1:1
in testFinal2():finally 肯定会被执行的!
test2:try
in testFinal3():finally 肯定会被执行的!
test3:try finally
in testFinal4():finally 肯定会被执行的!
test4:return in finally
* try finally特性:
在try中的return语句会将返回结果值压栈,然后转入到finally子过程,等到finally子过程执行完毕之后
(没有return),再返回。
finally的语句是在方法return之前执行的,而且如果finally中有return语句的话,方法直接结束,不再
返回栈中的值。
java中方法调用都是采用传值模式,所以如果在finally中改变了引用类型的对象的值,则return返回后
的结果也被改变。(实际上返回的是对象引用,并没有被改变,在finally中是直接对对象引用指向的
对象进行了修改)
在一个try-finally 语句中,finally 语句块总是在控制权离开try 语句块时执行的。
当try 语句块和finally 语句块都意外结束时,在try 语句块中引发意外结束的原因将被丢弃,而整个try-finally
语句意外结束的原因将于finally 语句块意外结束的原因相同。
总之,每一个finally 语句块都应该正常结束,除非抛出的是不受检查的异常。
千万不要用一个return、break、continue 或throw 来退出一个finally 语句块,并且千万不要允许将一个受
检查的异常传播到一个finally 语句块之外去。
如果一个catch 子句要捕获一个类型为E 的被检查异常,而其相对应的try 子句不能抛出E 的某种子类型的
异常,那么这就是一个编译期错误。但是捕获Exception 或Throwble 的catch 子句是合法的,不管与其
相对应的try 子句的内容为何。
System.exit 将立即停止所有的程序线程,它并不会使finally 语句块得到调用,但是它在停止VM 之前会
执行关闭挂钩操作。
//当你处理IO流,在finally 语句块中调用close 方法时,要用一个嵌套的try-catch语句来保护它,以防止IOException 的传播。 static void copy(String src, String dest) throws IOException { InputStream in = null; OutputStream out = null; try { in = new FileInputStream(src); out = new FileOutputStream(dest); byte[] buf = new byte[1024]; int n; while ((n = in.read(buf)) > 0) out.write(buf, 0, n); } finally { //in可能抛出异常导致out无法关闭。 //if (in != null) in.close(); //if (out != null) out.close(); closeIgnoringException(in); closeIgnoringException(out); } } private static void closeIgnoringException(Closeable c) { if (c != null) { try { c.close(); } catch (IOException ex) { // There is nothing we can do if close fails } } }