为什么这样做
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
而不是这个
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
为什么这样做
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
而不是这个
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
因为如果在执行块之后抛出异常,则除非捕获到异常,否则不会引发任何代码。try
无论块内发生什么,一个块总是被执行。finally
try
看看你的 catch 块 - 它会抛出DAOException
。因此,即使在您给出的示例中,您的 catch 块之后的语句也不会被执行。您所展示的(将一个异常包装在另一个中)是一种常见模式 - 但另一种可能性是 catch 块“意外”抛出异常,例如因为它进行的一个调用失败。
此外,您可能没有捕获其他异常——要么是因为您已声明该方法会抛出它们,要么是因为它们是未经检查的异常。你真的想因为IllegalArgumentException
被扔到某个地方而泄露资源吗?
因为如果抛出异常,
finally 子句中的代码将在异常向外传播时执行,即使异常中止了其余的方法执行;
try/catch 块之后的代码不会被执行,除非异常被 catch 块捕获并且不会重新抛出。
根据 HeadFirst Java,即使 try 或 catch 块有 return 语句,finally 块也会运行。流程跳转到 finally 然后返回返回。
因为它确保 finally 块中的内容被执行。catch 之后的东西可能不会被执行,例如,catch 块中有另一个异常,这是很有可能的。或者你只是做你所做的,并抛出一个包装原始异常的异常。
finally 关键字保证代码被执行。在您的底部示例中,不执行关闭语句。在上面的示例中,它们被执行(你想要什么!)
您的第二种方法不会执行“关闭”语句,因为它已经离开了该方法。
这是避免资源泄漏的方法
如果捕获所有错误,则应该没有区别,否则,只会执行 finally 块中的代码,因为代码执行顺序是:finally 代码 -> 错误抛出 -> catch 之后的代码 因此,一旦您的代码抛出任何未处理的错误,只有 finally代码块按预期工作。
finally 块中的代码将在从 catch 块中重新抛出异常之前被调用。这可确保您在 finally 块中放置的任何清理代码都会被调用。finally 块之外的代码将不会运行。
考虑 catch 可以向调用堆栈中的更高级别函数抛出异常。这将导致调用 final 在将异常抛出到上层之前。
在http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html这是误导性的(并且可能是问题的根源):
The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.
1. The new FileWriter statement fails and throws an IOException.
2. The list.get(i) statement fails and throws an IndexOutOfBoundsException.
3. Everything succeeds and the try block exits normally.
第4 种方式(除了IOException
和之外的异常IndexOutOfBoundsException
被抛出)丢失。上一页中描述的代码在诉诸finally
.
我也是 Java 新手,在找到这篇文章之前也有同样的疑问。一般而言,潜在记忆倾向于更多地依赖于例子而不是理论。
finally 块可能并不总是运行,请考虑以下代码。
public class Tester {
public static void main(String[] args) {
try {
System.out.println("The main method has run");
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("The finally block has run");
}
}
}
在您的情况下,我建议将 finally 块中的代码包装到 try/catch 中,因为此代码显然可能会引发异常。
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
try {
cs.close();
rs.close();
} catch (Exception e) {
//handle new exception here
}