在Java 6中模拟try-with-resources的最佳方法是什么?
事实certificate,几乎没有人正确地关闭Java中的资源。 程序员根本不使用try-finally
块,或者只是将resource.close()
放在finally
中也是不正确的(因为来自close()
Throwable
可以从try块中影响Throwable
)。 有时它们会放置像IOUtils.closeQuietly()
这样的东西,它只适用于InputStream
,但不适用于OutputStream
。 try-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。