Java 8 - 在异常情况下关闭流?

4

如果在构建流链的任何元素调用期间发生异常,是否有一种方法可以关闭流?

例如,以下代码:

    Stream.of(new Object())
            .filter(e -> {
                if (true) throw new IllegalStateException();
                return true;
            })
            .onClose(() -> System.out.println("OnClose"))
            .collect(Collectors.toList());

将会产生以下输出:
Exception in thread "main" java.lang.IllegalStateException
at my.className.lambda$main$2(LdapRealm.java:114)
at my.className$$Lambda$1/1607521710.test(Unknown Source)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at my.className.main(LdapRealm.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

请注意,由于未调用onClose()方法,因此未打印“OnClose”消息。 如果我希望该流被第三方代码使用,并且不确定该代码是否使用try/catch + Autocloseable功能,则是否有解决此问题的好方法?
2个回答

8
如果你的类的用户没有使用try/finally或try-with-resources,那么你无法做任何清理工作。(除了终结器,这不是一个好的解决方案。)
如果你有一个返回流的函数
Stream<Object> getStream() {
    return Stream.of(new Object())
        .filter(e -> {
            if (true) throw new IllegalStateException();
            return true;
        })
        .onClose(() -> System.out.println("OnClose"));
}

那么这个函数的正确使用方法是:
List<Object> result;
try (Stream<Object> s = getStream()) {
    result = s.collect(Collectors.toList());
}

看起来没有其他事情要做了,感谢您的回复。 - Askar Kalykov

3

因为StreamBaseStream的子类,而BaseStream又扩展了AutoClosable,所以你应该可以使用try-with-resource模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接