在Java 6中模拟try-with-resources的最佳方法是什么?

事实certificate,几乎没有人正确地关闭Java中的资源。 程序员根本不使用try-finally块,或者只是将resource.close()放在finally中也是不正确的(因为来自close() Throwable可以从try块中影响Throwable )。 有时它们会放置像IOUtils.closeQuietly()这样的东西,它只适用于InputStream ,但不适用于OutputStreamtry-with-resources解决了所有这些问题,但仍然有大量用Java 6编写的项目。

在Java 6中模拟try-with-resources的最佳方法是什么? 现在我使用Guava Closer ,它比什么都好,但仍然比try-with-resources更丑。 此外,还有一种称为贷款模式的模式,但Java中缺少lambdas使得这种模式非常麻烦。 有没有更好的办法?

我找到了一个很好的替代try-with-resources 。 它使用具有注释处理的Lombok库:

  @Cleanup InputStream in = new FileInputStream(args[0]); @Cleanup OutputStream out = new FileOutputStream(args[1]); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } 

但是,它不能正确处理exception。 此错误已超过1年但仍未关闭: https : //code.google.com/p/projectlombok/issues/detail?id = 384

尽管匿名类非常冗长,但它在java版本中仍然可以接受

  new TryWithResource(){ protected InputStream init() throws Exception { return new FileInputStream("abc.txt"); } protected void use(InputStream input) throws Exception{ input.read(); } }; ---- abstract class TryWithResource { abstract protected R init() throws Exception; abstract protected void use(R resource) throws Exception; // caution: invoking virtual methods in constructor! TryWithResource() throws Exception { // ... code before R r = init(); use(r); // ... code after } } 

如果IOUtils.closeQuietly唯一的问题是它忽略了OutputStreams上的exception,那么你可以简单地对它们调用close() ,或者创建你自己的实用程序类,它会自动处理两者,如下所示:

 public static void close(Closeable resource) { try { resource.close(); } catch(Exception e) { //swallow exception } } public static void close(OutputStream o) { //throw any exceptions o.close(); } 

在所有常见情况下,将在编译时选择正确的重载方法,但如果您将OutputStream作为Closeable传递,则必须更改此方法以执行动态instanceof检查以确保OutputStream始终抛出exception。