簡體   English   中英

Java 8 - 在Exception上關閉流?

[英]Java 8 - closing stream on Exception?

如果在調用構建流鏈的任何元素期間發生異常,是否有一種方法可以關閉Stream?

例如,代碼:

    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功能,是否有任何解決此問題的好方法?

如果您的類的用戶不使用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());
}

由於StreamBaseStream的子類,而BaseStream擴展了AutoClosable ,因此您應該能夠使用try-with-resource模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM