当代码抛出一个异常时, 就会终止方法中剩余代码的处理,并退出这个方法的执行。如果方法获得了一些本地资源,并且只有这个方法自己知道,又如果这些资源在退出方法之前必须被回收,那么就会产生资源回收问题。一种解决方案是捕获并重新抛出所有的异常,这种解决方案并不完美,这是因为需要在两个地方清除所分配的资源。一个在正常的代码中;另一个在异常代码中。
Java 有一种更好的解决方案,这就是 finally 子句。下面将介绍 Java 中如何恰当地关闭一个文件。如果使用 Java 编写数据库程序,就需要使用同样的技术关闭与数据库的连接。当发生异常时,关闭所有数据库的连接是非常重要的。不管是否有异常被捕获,finally 子句中的代码都被执行。在下面的示例中, 程序将在所
有情况下关闭文件:
InputStream in = new FileInputStream(. . .);
try{
code that might throwexceptions
}catch (IOException e) { // 3
showerror message
// 4
}finally{ // 5
in.close();
}
在上面这段代码中,有下列 3 种情况会执行 finally 子句:
1 ) 代码没有抛出异常。 在这种情况下, 程序首先执行 try 语句块中的全部代码,然后执行 finally 子句中的代码t 随后, 继续执行 try 语句块之后的第一条语句。也就是说,执行标注的 1、 2、 5、 6 处。
2 ) 抛出一个在 catch 子句中捕获的异常。在上面的示例中就是 IOException 异常。在这种情况下,程序将执行 try语句块中的所有代码,直到发生异常为止。此时,将跳过 try语句块中的剩余代码,转去执行与该异常匹配的 catch 子句中的代码, 最后执行 finally 子句中的代码。如果 catch 子句没有抛出异常,程序将执行 try 语句块之后的第一条语句。在这里,执行标注 1、 3、 4、5、 6 处的语句。如果 catch 子句抛出了一个异常, 异常将被抛回这个方法的调用者。在这里, 执行标注1、 3、 5 处的语句。
3 ) 代码抛出了一个异常, 但这个异常不是由 catch 子句捕获的。在这种情况下,程序将执行 try 语句块中的所有语句,直到有异常被抛出为止。此时, 将跳过 try 语句块中的剩余代码, 然后执行 finally 子句中的语句, 并将异常抛给这个方法的调用者。在这里, 执行标注 1、 5 处的语句。
try 语句可以只有 finally 子句,而没有 catch 子句。例如,下面这条 try 语句:
InputStream in = . .
try{
code that might throwexceptions
}finally{
in.close();
}
警告:当 finally 子句包含 return 语句时, 将会出现一种意想不到的结果„ 假设利用 return语句从 try语句块中退出。在方法返回 前,finally 子句的内容将被执行。如果 finally 子句中也有一个 return 语句,这个返回值将会覆盖原始的返回值。如:
public static int f(int n) {
try{
int r = n * n;
return r;
}finally{
if (n = 2) return 0;
}
}
如果调用 f(2), 那么 try 语句块的计算结果为 r =

最低0.47元/天 解锁文章
760

被折叠的 条评论
为什么被折叠?



