如果在 finally 块中抛出异常,finally 块是否会完全执行?

9

这里有一些代码,我不确定如果reader.close()方法抛出异常,它会如何反应。

public void someMethod(String s) throws IOException{
   BufferedReader reader = Files.newBufferedReader(filePath,cs);
   listRWLock.readLock().lock();
   try{
     //miscellaneous code involving reading
   }finally{
     reader.close()
     listRWLock.readLock().unlock()
   }
}

ListRWLock是一个可重入的ReentrantReadWriteLock。如果reader.close()方法抛出异常,那么它后面的语句会执行失败吗?我尝试搜索了这个主题,虽然我找到了一些关于finally在return语句中执行的内容,但我没有找到有关在finally块内抛出异常时会发生什么的详细信息。
提前谢谢。

1
以下语句不应执行。此外,finally块中的return可能会覆盖先前的异常。 - S.D.
4个回答

4
基本上,finally子句存在是为了确保资源得到正确释放。但是,如果在finally块内抛出异常,则该保证将消失。
一个没有非常好的解决方案的问题是,finally块中的代码本身可能会引发异常。在这种情况下,finally块中的异常将从异常中抛出,而不是在try块内发生任何异常。由于finally块中的代码旨在作为“清理”代码,请我们将在其中发生的异常视为次要,并设置显式catch:
public int readNumber(File f) throws IOException, NumberFormatException {
  BufferedReader br = new BufferedReader(new
    InputStreamReader(new FileInputStream(f), "ASCII"));
  try {
    return Integer.parseInt(br.readLine());
  } finally {
    try { br.close(); } catch (IOException e) {
      // possibly log e
    }
  }
}

关于 finally 代码块的其他一些注意事项:

  1. 在 finally 块中返回一个值时,有一个同样的“覆盖”问题,就像我们在异常处理中提到的那样:这会覆盖 try 块里本来想要返回的任何值。实际上,在 finally 块中返回值的情况很少见,也不建议这样做。
  2. 实际上退出程序(通过调用 System.exit() 或者引发导致进程中止的致命错误:有时在 Windows 中称为“热点”或“Dr Watson”)将阻止执行 finally 代码块!
  3. 嵌套使用 try/catch/finally 代码块没有限制(例如,在 try/catch 块内放置一个 try/finally 块,反之亦然),这并不是什么罕见的事情。

你直接从这里这里抄袭并混合了你的答案?至少要诚实地给他们点赞才行! - Kumar Manish

4
您可以像这样做:
try{
    //miscellaneous code involving reading
}finally{
   handlePossibleException(reader);
   listRWLock.readLock().unlock()
}

handlePossibleException(BufferedReader reader) {
    try {
         if (reader != null) {
             reader.close();
         }
    } catch( Exception e ) {
      log.e( "reader.close() Exception: ", e );
      }
} 

1

我建议您进行测试,

但是如果try语句出现IO异常,那么您的读取器将不会关闭。

可能存在其他方案。

catch(IOException ex){ 
         reader.close()

1

异常可能会发生在代码的任何位置,包括finally块中,因此您必须像在代码的其他位置一样捕获它。查看以下帖子以获取有关处理此类情况的方法的一些想法:

在finally块中抛出异常


不回答问题。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接