2013-12-19 44 views
1

在下面的代码中,close应该放在哪里?它应该在try语句还是finally语句中?如果终于,它是否应该与另一个尝试抓住?谢谢。我应该在哪里放置close()方法?

PrintWriter out = null; 
try { 
    out = new PrintWriter(
      new BufferedWriter(
       new FileWriter("out.txt", true))); 
    out.println("the text"); 
} catch (IOException e) { 
    System.err.println(e); 
} finally { 
    if (out != null) { 
     out.close(); 
    } 
} 
+5

无论如何finally块都会被执行。所以我认为把它放在那里是正确的。 – sanket

+1

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – HectorLector

+5

如果使用1.7或更高版本,请使用['try-with-resources'](http://docs.oracle.com/javase /tutorial/essential/exceptions/tryResourceClose.html) – khachik

回答

0

要正确处理close,应确保调用是否在主线代码中发生异常,但还应确保在主线后发生异常并调用close,然后抛出一个例外本身,它不会导致主线例外被丢弃;取决于各种因素,包括对象是否打开供读取或写入,可能需要让主线例外渗透(可能封装有关关闭失败的信息),记录或封装主线例外但具有close失败渗透,或抛出一个“双重错误”的例外,它封装了其他两个。

的Java 7的尝试 - 以资源功能提供了多种场景相当不错的表现:如果try,另一个在close发生异常,后者例外被添加到抑制异常的列表(异常处理代码应该寻找)。如果一种方法应该从无线传感器获取数据并将其写入文件,并且如果调用者期望在传感器故障的情况下该文件将保存与成功读取的信息一样多的信息,则无法关闭文件可能比传感器故障更重要[如果传感器例如只包括“返回最旧的项目”和“删除最旧的项目”命令,然后如果文件关闭正确传感器通信期间的异常意味着传感器中不再有任何数据将在文件中。如果文件没有正确关闭,那意味着可能会有永久的数据丢失,并且应该告诉某人。

处理“传感器捕获”情况的代码最终会有点恶心:传感器读取逻辑将被放置在try块中,其finally将捕获任何变量异常。然后finally块将不得不使用它自己的try块关闭;如果发生异常,则抛出一个自定义writeFileCloseFailure异常,它封装try块的异常(如果有)和close的异常;否则,重新抛出try块中的异常(如果有)。请注意,由于ioException可能表示无法从传感器获取数据(有点预期并且可以忍受)或无法写入文件(非常糟糕),因此使用另一种异常类型进行包装可以使主叫方区分这些情况。

3

把它放在finally块中。

因为无论是哪种情况(例外情况或无例外情况),都应关闭Writer

4

请参阅try-with-resources的文档。如果您至少使用Java 7,则有一个很好的语法。否则,finally块是适当的,因为它应该在正常情况和例外情况下都关闭。