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

时间:2014-09-28 05:03:02

标签: java exception bufferedreader finally

所以我在这里有一些代码,我不确定如果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()方法抛出异常,那么它之后的语句是否会无法执行?我已经尝试过搜索这个主题了,虽然我已经知道了一些关于在返回语句中最终执行的内容,但是我还没有设法找到如果在内部抛出异常会发生什么的细节。最后阻止。

提前致谢。

4 个答案:

答案 0 :(得分:4)

基本上,最后的条款是为了确保正确释放资源。但是,如果在finally块中抛出异常,则该保证会消失。

没有真正解决方案的问题是finally块中的代码本身可能会抛出异常。在这种情况下,finally块中的异常将从异常中抛出,而不是在try块内发生的任何异常。由于finally块中的代码旨在成为“清理”代码,因此我们可以决定将那里发生的异常视为次要代码,并设置一个明确的捕获:

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块(for 例如,将try / finally块放在try / catch块中,或者 反之亦然),这并不是一件不寻常的事情。

答案 1 :(得分: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 );
      }
} 

答案 2 :(得分:1)

你应该测试一下,

但是如果尝试抛出IO Exception,那么你的读者就不会关闭。

也许有

catch(IOException ex){ 
         reader.close()

答案 3 :(得分:1)

代码中的任何地方都可能发生异常,包括finally阻止,因此您必须将其捕获到代码中的任何其他位置。请查看以下帖子,了解有关处理此类情况的方法:

throws Exception in finally blocks