[英]What is the gist of finally block in Java?
我想以下例子; 但无法弄清楚finally块的重要性是什么。 你能告诉我这两个代码示例的执行区别吗? 现实生活中的例子也很有帮助。
样本1:
try{
// some code 1
}catch(Exception ex){
// print exception
}finally{
// some code 2
}
样本2:
try{
// some code 1
}catch(Exception ex){
// print exception
}
// some code 2
你提出的两个片段有很大的不同,例如当catch
块本身抛出一个异常时, finally
块仍然会被它的语义执行。
这是以下片段打印"Finally!"
,但不是"What about me???"
:
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
一般来说, try
块的finally
实际上总是被执行。 try
块之后的任何代码都没有这样的保证。
但是,如果我的
catch
块只是一个简单的
仍然无法保证它不会throw
东西。 在例如异常详细消息的构造中,仍然可能出现问题。
即使您尽最大努力保证catch
代码是“安全的”并且try
语句后面的代码将始终执行,那么问题就变成“为什么?”。 为什么finally
要避免,然后再努力复制它的语义?
finally
语义是有保证的,不需要代码的编写者或读者的证据负担。 也正因为如此,它是地道的使用finally
阻止把强制“清理”代码。 使用finally
保证正确性并增强可写性和可读性。
即使抛出了一个Error
,也会执行finally
块,这不会被示例中的catch
块catch
。 因此,您可以将清理代码放在finally
块中,该块应始终运行,而不管try
和catch
块中的操作结果如何。
请注意,通常catch
块捕获更多特定类型的异常 - 通常只检查异常 - 因此在大多数情况下,上面两个代码示例之间的差异是非常明确的。
更新:您可能会说您的catch
块永远不会抛出异常,因此finally
不需要。 但请注意两件事:
catch
块中添加一些可能引发异常的代码,会记得将清理后的代码放到finally
块? try-catch-finally
是一种编程习惯用法 ,它使人们更容易阅读代码来理解正在发生的事情。 如果你不使用常用的习语,就会产生误解,从而导致长期的错误。 您使用finally
块来清理并运行任何应该运行的代码,无论是否抛出(和捕获)异常。 这包括catch
块中的代码。
当我们想要释放我们在try块中使用的资源时,它会很有用。 因此,在任何情况下执行它们而不丢失的唯一地方是最终阻止。 因为如果抛出异常,java不会执行之后立即执行的代码。 它直接跳转到catch块。
请注意,您甚至可以在没有catch的情况下尝试finally:
try{
// some code
}finally{
// cleanup code
}
因此,一个示例可能是一种想要将异常传播给调用者的方法,但仍需要清理代码,例如释放外观。
如果try块中的语句抛出未经检查的异常,则最终将执行块以允许程序员采取相关操作。
在现实生活中,即使发生异常,finally块也用于关闭打开的资源。 例如,当您读取(或写入)文件,访问数据库等时。
public void readFile(String fileName) {
FileReader fr;
BufferedFileReader bfr;
try {
fr = new FileReader(fileName);
bfr = new BufferedFileReader(fr);
// ...
} catch (IOException ioe) {
// ...
} finally {
// TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
if (bfr != null) {
try {
bfr.close();
} catch (IOException ignoredIOE) {}
}
if (fr != null) {
try {
fr.close();
} catch (IOException ignoredIOE) {}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.