Java8 中 "Autocloseable" 的数组或集合
Array or collection of "Autocloseable" in Java8
Autocloseable
应始终与 try-with-resources
一起使用。至少 Intellij 检查表明它。
所以,如果我有一个代码生成 Foo
实现 Autocloseable
我应该这样做:
try (final Foo foo = getFoo()) {
foo.doSomething();
}
但是如果我有 returns Foo[]
的函数呢?或者接受 Foo[]
(或 Collection<Foo>
)作为参数的函数?
如何将它与 try-with-resources
一起使用?
查看以下功能:
Foo[] getFoos();
doAll(Foo... foo);
我想做点什么行doAll(getFoos())
我该怎么做?
Try-with-resources 语句只能关闭那些在其 header 中声明和分配的资源。所以唯一的方法是让你得到的 Collection 实现 AutoCloseable 或者将它包装到你的 AutoCloseable 扩展中,所以它的 close() 方法将被 T-W-R 调用。喜欢:
try (SomeAutoCloseableCollction col = getAutoCloseables()) {
System.out.println("work");
} //col.close() gets called
对于数组,恐怕没有办法,因为你不能扩展它并使它实现一些接口。
如果您要自己关闭 collection,可以查看 Apache Drill project and class org.apache.drill.common.AutoCloseables
- 它就是这样做的,它自己关闭了很多 AutoCloseables。
正如其他答案所说,这实际上是不可能的。但是,您应该问问自己为什么需要将整个集合放入 AutoCloseable 中。如果你想确保每个元素在处理后都关闭,你可以这样做:
Foo[] foos = getFoos();
for (int i = 0; i < foos.length; i++) {
try (Foo foo = foos[i]) {
// Your code here
}
}
您可以创建将 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
*/
}
Autocloseable
应始终与 try-with-resources
一起使用。至少 Intellij 检查表明它。
所以,如果我有一个代码生成 Foo
实现 Autocloseable
我应该这样做:
try (final Foo foo = getFoo()) {
foo.doSomething();
}
但是如果我有 returns Foo[]
的函数呢?或者接受 Foo[]
(或 Collection<Foo>
)作为参数的函数?
如何将它与 try-with-resources
一起使用?
查看以下功能:
Foo[] getFoos();
doAll(Foo... foo);
我想做点什么行doAll(getFoos())
我该怎么做?
Try-with-resources 语句只能关闭那些在其 header 中声明和分配的资源。所以唯一的方法是让你得到的 Collection 实现 AutoCloseable 或者将它包装到你的 AutoCloseable 扩展中,所以它的 close() 方法将被 T-W-R 调用。喜欢:
try (SomeAutoCloseableCollction col = getAutoCloseables()) {
System.out.println("work");
} //col.close() gets called
对于数组,恐怕没有办法,因为你不能扩展它并使它实现一些接口。
如果您要自己关闭 collection,可以查看 Apache Drill project and class org.apache.drill.common.AutoCloseables
- 它就是这样做的,它自己关闭了很多 AutoCloseables。
正如其他答案所说,这实际上是不可能的。但是,您应该问问自己为什么需要将整个集合放入 AutoCloseable 中。如果你想确保每个元素在处理后都关闭,你可以这样做:
Foo[] foos = getFoos();
for (int i = 0; i < foos.length; i++) {
try (Foo foo = foos[i]) {
// Your code here
}
}
您可以创建将 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
*/
}