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");
}
}
}
このラッパーには少なくとも 2 つの問題があります。
- 「bad-path」が無効で割り当てが
r2
スローされる場合、r1
は閉じられません。 - ラッパーの構築が成功した後に
r1.close
スローされた場合、r2
は閉じられません。
これらの問題はすべて対処できますが、2 つのリソースのみをラップする場合でも、ラッパーの作成は非常に簡単ではなく、エラーが発生しやすくなります。
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");
}
}
}
ラッパーの作成を容易にするヘルパー クラスまたはその他の方法はありますか?