在资源试用块中管理多个链接资源的正确习语?
Java 7 try-with-resources 语法(也称为 ARM 块(自动资源管理))在仅使用一个资源时很好,简短且简单明了。但是,当我需要声明相互依赖的多个资源时,我不确定正确的习语是什么,例如a和a包装它。当然,这个问题涉及包装某些资源时的任何情况,而不仅仅是这两个特定的类。AutoCloseable
FileWriter
BufferedWriter
AutoCloseable
我想出了以下三个替代方案:
1)
我见过的幼稚习语是在 ARM 托管变量中仅声明顶级包装器:
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
这很好,很短,但它坏了。由于基础不是在变量中声明的,因此它永远不会直接在生成的块中关闭。它只能通过包装的方法关闭。问题是,如果从 的构造函数引发异常,则不会调用它,因此基础不会被关闭。FileWriter
finally
close
BufferedWriter
bw
close
FileWriter
2)
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
在这里,底层资源和包装资源都是在ARM托管变量中声明的,因此它们肯定会被关闭,但底层将被调用两次:不仅直接,而且通过包装。fw.close()
bw.close()
对于这两个都实现的特定类(这是 的子类型),这应该不是问题,它们的协定声明允许多次调用:Closeable
AutoCloseable
close
关闭此流并释放与其关联的任何系统资源。如果流已关闭,则调用此方法不起作用。
但是,在一般情况下,我可以拥有仅实现(而不是)的资源,这并不能保证可以多次调用:AutoCloseable
Closeable
close
请注意,与 java.io.Closeable 的 close 方法不同,此 close 方法不需要是幂等的。换句话说,多次调用此 close 方法可能会产生一些明显的副作用,这与 Closeable.close 不同,Closeable.close 在多次调用时不需要产生任何影响。但是,强烈建议此接口的实现者使其 close 方法具有幂等性。
3)
static void printToFile3(String text, File file) {
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
此版本在理论上应该是正确的,因为只有 表示需要清理的真实资源。本身不持有任何资源,它只委托给 ,因此仅关闭底层应该足够了。fw
bw
fw
fw
另一方面,语法有点不规则,而且,Eclipse发出警告,我认为这是一个假警报,但它仍然是一个警告,必须处理:
资源泄漏:“bw”从未关闭
那么,选择哪种方法呢?还是我错过了其他一些正确的成语?