我可以避免这种繁琐的尝试……捕获块

通常,在处理Java IO代码时,这是我写的

FileOutputStream out = null; try { out = new FileOutputStream("myfile.txt"); // More and more code goes here... } catch (Exception e) { } finally { // I put the close code in finally block, to enture the opened // file stream is always closed even there is exception happened. if (out != null) { // Another try catch block, troublesome. try { out.close(); } catch (IOException ex) { } } } 

正如您所看到的,当我尝试关闭文件流时,我需要处理另一个try … catch块。

看起来很麻烦:(

有什么办法可以避免吗? 将close代码放在非finally块中感觉不舒服,因为其他代码引起的exception将无法调用“close”。

在finally中关闭流是非常重要的。 您可以使用实用程序方法简化此过程,例如:

 public static void closeStream(Closeable closeable) { if(null != closeable) { try { closeable.close(); } catch(IOException ex) { LOG.warning("Failed to properly close closeable.", ex); } } } 

我认为至少记录一个流关闭失败。 然后用法变为:

 FileOutputStream out = null; try { out = new FileOutputStream("myfile.txt"); // More and more code goes here... } catch (Exception e) { } finally { closeStream(out); } 

在Java 7中,我相信流将自动关闭,并且对这些块的需求应该是多余的。

自动资源管理即将推出Java 7,它将自动提供对此的处理。 在此之前,诸如OutputStreamInputStream等对象实现了自Java 5以来的Closeable接口。我建议您提供一种实用方法来安全地关闭它们。 这些方法通常会占用exception,因此请确保在想要忽略exception时仅使用它们(例如,在finally方法中)。 例如:

 public class IOUtils { public static void safeClose(Closeable c) { try { if (c != null) c.close(); } catch (IOException e) { } } } 

请注意, close()方法可以多次调用,如果它已经关闭,后续调用将不起作用,因此在try块的正常操作期间还提供关闭调用,其中不会忽略exception。 从Closeable.close文档 :

如果流已经关闭,则调用此方法无效

因此,在常规的代码流中关闭输出流,而safeClose方法只有在try块中出现故障时才会执行close:

 FileOutputStream out = null; try { out = new FileOutputStream("myfile.txt"); //... out.close(); out = null; } finally { IOUtils.safeClose(out); } 

讨论在

尝试捕获 – 最后再尝试捕获

是否优先使用嵌套的try / catch块?

基本上,问题是close()exception是否值得捕获。

Project Lombok提供了一个@Cleanup注释,它不再需要try catch块。 这是一个例子 。

我倾向于使用实用function:

 public static void safeClose(OutputStream out) { try { out.close(); } catch (Exception e) { // do nothing } } 

这将代码更改为更可口:

 FileOutputStream out = null; try { out = new FileOutputStream("myfile.txt"); // do stuff } catch (Exception e) { // do something } finally { safeClose(out); } 

至少在Java 7(有希望) ARM(“自动资源管理”)块有所帮助之前,你无法在Java中做得更好。

写一个看起来像下面的方法; 来自你的最后一块…

 static void wrappedClose(OutputStream os) { if (os != null) { try { os.close(); } catch (IOException ex) { // perhaps log something here? } } 

分开你的try / catch和try / finally块。

 try { FileOutputStream out = new FileOutputStream("myfile.txt"); try { // More and more code goes here... } finally { out.close(); } } catch (Exception e) { //handle all exceptions } 

外部捕获物也将捕获关闭时抛出的任何东西。