Rya*_*ing 7 java java-8 try-with-resources autocloseable
AutoCloseable我正在一个块中创建可变数量的对象try-with-resources。在任何退出点,我都希望关闭所有分配的资源。
我可以想象自己写一些东西来做到这一点,但是是否有一个类似于Python 的 contextlib.ExitStack 的现有实用程序可以关闭分配的资源?我希望它看起来像这样:
try (ExitStack exitStack = new ExitStack()) {
List<Widget> widgets = new ArrayList<>();
for (...) {
widgets.add(exitStack.add(new Widget()));
}
// use widgets
}
Run Code Online (Sandbox Code Playgroud)
(注意:这不是这个问题,因为我不知道我会提前拥有多少资源。
嘿,亲密的选民,我不是在要求一个库,我是在问你如何完成安全关闭动态数量的任务AutoCloseable,如果有一个语言功能,那就太好了,如果有一个标准库函数,也很棒,如果我必须自己写,那很好。如果您想推荐一个常用的包含此内容的第三方库,那么当然可以。
鉴于这个实用程序似乎不存在,我编写了一个。它包装所有抛出的异常,然后仅在资源的 close() 抛出时抛出。返回之前始终关闭所有内容。
public class ClosingException extends Exception { }
Run Code Online (Sandbox Code Playgroud)
和
import java.util.Deque;
import java.util.ArrayDeque;
public final class ClosingStack implements AutoCloseable {
public void close() throws ClosingException {
ClosingException allClosingExceptions = new ClosingException();
while (!resources.isEmpty()) {
try {
resources.removeLast().close();
} catch (Throwable e) {
allClosingExceptions.addSuppressed(e);
}
}
if (allClosingExceptions.getSuppressed().length != 0) {
throw allClosingExceptions;
}
}
public <T extends AutoCloseable> T add(T resource) {
resources.addLast(resource);
return resource;
}
private Deque<AutoCloseable> resources = new ArrayDeque<>();
}
Run Code Online (Sandbox Code Playgroud)
并使用:
try (ClosingStack closingStack = new ClosingStack()) {
List<Widget> widgets = new ArrayList<>();
for (...) {
widgets.add(closingStack.add(new Widget()));
}
// use widgets
}
Run Code Online (Sandbox Code Playgroud)