a) The constructor cannot use try-with-resources nor try-finally because the resources shall not be closed in case the resources can be created successfully. Instead the creation of a resource should be followed by a try-catch block that makes sure the resource is closed in case of any error that follows its creation. Inside the catch block the exception has to be rethrown so it is not lost.
b) the close method can use a try-with-resource block to make sure all resources are closed
public class MyClass implements AutoCloseable {
private final SomeResource resource1;
private final SomeResource resource2;
private final SomeResource resource3;
MyClass() throws IOException {
resource1 = new SomeResource();
try {
resource2 = new SomeResource();
try {
resource3 = new SomeResource();
} catch (IOException | RuntimeException e) {
closeIgnoreException(resource2);
throw e;
}
} catch (IOException | RuntimeException e) {
closeIgnoreException(resource1);
throw e;
}
}
private static void closeIgnoreException(AutoCloseable autoCloseable) {
try { autoCloseable.close(); } catch (Exception ignore) {}
}
@Override
public void close() throws IOException {
try (resource1;
resource2;
resource3) {}
}
}
Prior to Java 9 the try-with-resources statement accepted no references. Therefore the close
method had to be realized in the following way:
public void close() throws IOException {
try (SomeResource r1 = resource1;
SomeResource r2 = resource2;
SomeResource r3 = resource3) {}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…