Java8中的"Autocloseable"数组或集合

use*_*142 7 java java-8 try-with-resources autocloseable

Autocloseable应始终使用try-with-resources.至少Intellij检查表明了这一点.所以,如果我有一个生成Foo该实现的代码,Autocloseable我应该这样做:

try (final Foo foo = getFoo()) {
    foo.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

但是如果我有功能返回Foo[]怎么办?或接受Foo[](或Collection<Foo>)作为其参数的函数?

我怎么用它try-with-resources?查看以下功能:

Foo[] getFoos();
doAll(Foo... foo);
Run Code Online (Sandbox Code Playgroud)

我想做点什么 doAll(getFoos())

我怎样才能做到这一点?

Iga*_*and 6

Try-with-resources语句只能关闭在其标头中声明和分配的那些资源.所以唯一的方法是让你得到的集合实现AutoCloseable或将它包装到你的AutoCloseable扩展中,所以它的close()方法将由TWR调用.喜欢:

try (SomeAutoCloseableCollction col = getAutoCloseables()) {
        System.out.println("work");
}  //col.close() gets called
Run Code Online (Sandbox Code Playgroud)

对于一个数组,我担心没有办法,因为你无法扩展它并使它实现一些接口.


如果你要自己关闭收集,可能会看看Apache Drill项目和类org.apache.drill.common.AutoCloseables- 它确实如此,自己关闭了大量的AutoCloseables.


Hol*_*ger 6

您可以创建将AutoCloseables组合为一个可以安全关闭所有方法的方法:

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);
}
Run Code Online (Sandbox Code Playgroud)

他们允许使用数组返回方法,如

Foo[] foo;
try(AutoCloseable closeAll = MyClass.closeAll(foo=getFoos())) {
    /*
        use foo
    */
}
Run Code Online (Sandbox Code Playgroud)