try
AutoCloseable
-with-resources 很好,但在我看来,在创建包装多个对象的类时,它仍然不足以进行有效的资源管理。例如,考虑
import java.io.*;
class AutocloseableWrapper implements AutoCloseable {
private FileReader r1;
private FileReader r2;
public AutocloseableWrapper(String path1, String path2) throws IOException {
r1 = new FileReader(path1);
r2 = new FileReader(path2);
}
@Override
public void close() throws IOException {
r1.close();
r2.close();
}
public static void main(String[] args) throws IOException {
try (AutocloseableWrapper w = new AutocloseableWrapper("good-path", "bad-path")) {
System.out.format("doing something\n");
throw new IOException("doing something in main");
}
}
}
这个包装器至少有两个问题:
- 如果“bad-path”无效并导致分配
r2
抛出,r1
则不关闭。 - 如果包装器构造成功但随后
r1.close
抛出,r2
则不关闭。
所有这些问题都可以解决,但是编写包装器变得非常重要且容易出错,即使只包装两个资源:
import java.io.*;
class AutocloseableWrapper implements AutoCloseable {
private FileReader r1;
private FileReader r2;
public AutocloseableWrapper(String path1, String path2) throws IOException {
r1 = new FileReader(path1);
try {
r2 = new FileReader(path2);
}
catch (IOException e) {
try {
r1.close();
}
catch (IOException e2) {
e.addSuppressed(e2);
}
throw e;
}
}
@Override
public void close() throws IOException {
IOException e = null;
try {
r1.close();
}
catch (IOException e1) {
e = e1;
}
try {
r2.close();
}
catch (IOException e2) {
if (e == null)
throw e2;
else {
e.addSuppressed(e2);
throw e;
}
}
}
public static void main(String[] args) throws IOException {
try (AutocloseableWrapper w = new AutocloseableWrapper("good-path", "bad-path")) {
System.out.format("doing something\n");
throw new IOException("doing something in main");
}
}
}
是否有一些帮助类或任何其他方法可以使编写包装器更容易?