Autocloseable
应始终与try-with-resources
一起使用。至少Intellij检查表明了这一点。
所以,如果我有一个产生Foo
的代码来实现Autocloseable
我应该这样做:
try (final Foo foo = getFoo()) {
foo.doSomething();
}
但是,如果我有返回Foo[]
的函数怎么办?或者接受Foo[]
(或Collection<Foo>
)作为参数的函数?
如何将其与try-with-resources
一起使用?
查看以下功能:
Foo[] getFoos();
doAll(Foo... foo);
我想做点doAll(getFoos())
我该怎么做?
答案 0 :(得分:5)
Try-with-resources语句只能关闭那些在其标题中声明和分配的资源。因此,唯一的方法是使您获得的集合实现AutoCloseable或将其包装到AutoCloseable扩展中,因此它的close()方法将由T-W-R调用。像:
try (SomeAutoCloseableCollction col = getAutoCloseables()) {
System.out.println("work");
} //col.close() gets called
对于阵列,我担心没有办法,因为你无法扩展它并使它实现一些接口。
如果您要自己关闭收藏,可以查看Apache Drill项目和班级org.apache.drill.common.AutoCloseables
- 它就是这样做,自行关闭大量AutoCloseables。
答案 1 :(得分:3)
您可以创建将AutoCloseable
组合到一个安全关闭所有方法的方法:
public static AutoCloseable closeBoth(AutoCloseable a, AutoCloseable b) {
if(a==null) return b;
if(b==null) return a;
return () -> { try(AutoCloseable first=a) { b.close(); } };
}
public static AutoCloseable closeAll(AutoCloseable... c) {
return Arrays.stream(c).reduce(null, MyClass::closeBoth);
}
他们允许使用像
这样的数组返回方法Foo[] foo;
try(AutoCloseable closeAll = MyClass.closeAll(foo=getFoos())) {
/*
use foo
*/
}
答案 2 :(得分:1)
正如另一个答案所说,这是不可能的。但是,您应该问自己为什么需要将整个集合放在AutoCloseable中。如果要确保在处理后关闭每个元素,可以执行以下操作:
Foo[] foos = getFoos();
for (int i = 0; i < foos.length; i++) {
try (Foo foo = foos[i]) {
// Your code here
}
}