try
-with-resources 很好,但在我看来,在创建包装多个 AutoCloseable
的类时,它仍然不足以进行有效的资源管理对象。例如,考虑
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");
}
}
}
是否有一些帮助类或任何其他方法可以使编写包装器更容易?
最佳答案
您应该启用由编译器解包的语法代码...您可以在这里找到 Oracle 文章:- http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html
说到这个问题,如果你有一个包装器,你可以做这样的事情
@Override
public void close() throws IOException {
Throwable t = null;
try {
r1.close();
} catch (Throwable t1) {
t = t1;
throw t1;
} finally {
if (t != null) {
try {
r2.close();
} catch (Throwable t2) {
t.addSuppressed(t2);
}
} else {
r2.close();
}
}
}
注意:由于 Java 中的精确重新抛出功能,这将起作用 7
关于java - 包装多个 AutoCloseables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24705055/