对于用户代码,有几个选项可以正确关闭多个资源:
try (
A a = new A();
B b = new B();
C c = new C()
) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
除了好而简短之外,这也是正确的。
a,b而c需要关闭。try/finally此处的改进,可以在此处阅读https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose .html)Closer对于JDK7之前的版本,有Guava Closer,其用法如下:
Closer closer = Closer.create();
try {
A a = closer.register(new A());
B b = closer.register(new B());
C c = closer.register(new C());
// ...
} catch (Throwable e) { // must catch Throwable
throw closer.rethrow(e);
} finally {
closer.close();
}
Run Code Online (Sandbox Code Playgroud)
虽然时间稍长,但效果也很好(有关更多信息,请参见https://github.com/google/guava/wiki/ClosingResourcesExplained#closer)
说我有:
public class P implements AutoCloseable {
private A a;
private B b;
private C c;
public P() {
a = new A();
b = new B();
c = new C();
}
public close() {
c.close();
b.close();
a.close();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码存在多个问题:
close)close,则不会关闭某些资源1个或2个都没有遭受这些问题的困扰。然而:
Closer似乎也不能使用。尽管它更灵活,但它不支持重投掷,这在构造函数中是必需的对于没有太多样板的N资源,这里的正确模式是什么?该解决方案还应具有抑制属性1和2
您可以使用围绕方法执行模式向资源包装类的用户隐藏资源的打开和关闭。这样您将确保资源始终处于关闭状态。您应该为不同的用例添加单独的操作方法。仅当这是公共资源并被应用程序的许多部分使用时,这才有用。
这是一个示例
public class ResourceWrapper {
private A a;
private B b;
private C c;
private ResourceWrapper() {
// add try catch if you have to, after cleanup then throw exception if ithappens
a = new A();
b = new B();
c = new C();
}
/**
* add required operation methods
*/
public ResourceWrapper op1() {
// do some operations
return this;
}
public ResourceWrapper op2() {
// if additional add or different
return this;
}
// close everything here
private void close() {
// check null if you have to
// add try catch if you have to
c.close();
b.close();
a.close();
}
public static void use(Consumer<ResourceWrapper> consumer) {
ResourceWrapper resource = null;
try {
resource = new ResourceWrapper();
consumer.accept(resource);
}
finally {
if(resource!=null) {
resource.close();
}
}
}
}
public class SampleResourceUser {
/*
* This represents the user of the Resource,
* User only cares about which operations that needs to be done on the resource.
* Opening and closing the resource wrapped around the operation methods by the owner of the Resource.
*
*/
public static void main(String[] args) {
ResourceWrapper.use(resource->resource.op1().op2());
}
}
Run Code Online (Sandbox Code Playgroud)