-
Bug
-
Resolution: Fixed
-
P4
-
None
-
b109
-
Verified
Currently BaseStream.onClose() allows to register new handlers even after the stream is already consumed or even closed and they're actually executed on the consequtive close() call:
Stream<String> s = Stream.of("content");
s = s.onClose(() -> System.out.println("A"));
s.forEach(System.out::println);
s = s.onClose(() -> System.out.println("B"));
s.close(); // prints A and B
s = s.onClose(() -> System.out.println("C"));
s.close(); // prints C
The same result also produced when removing "s =":
Stream<String> s = Stream.of("content");
s.onClose(() -> System.out.println("A"));
s.forEach(System.out::println);
s.onClose(() -> System.out.println("B"));
s.close(); // prints A and B
s.onClose(() -> System.out.println("C"));
s.close(); // prints C
On the other hand, AutoCloseable interface (which BaseStream extends) encourages idempotent close() method. I propose the following change:
* BaseStream.onClose() implementation (AbstractPipeline.onClose()) must throw IllegalStateException if the stream is already linked or consumed.
* The documentation for BaseStream.onClose() should state that implementation may throw IllegalStateException if terminal operation is already called or stream is already closed.
* BaseStream.close() implementation must do nothing if called the second time.
Stream<String> s = Stream.of("content");
s = s.onClose(() -> System.out.println("A"));
s.forEach(System.out::println);
s = s.onClose(() -> System.out.println("B"));
s.close(); // prints A and B
s = s.onClose(() -> System.out.println("C"));
s.close(); // prints C
The same result also produced when removing "s =":
Stream<String> s = Stream.of("content");
s.onClose(() -> System.out.println("A"));
s.forEach(System.out::println);
s.onClose(() -> System.out.println("B"));
s.close(); // prints A and B
s.onClose(() -> System.out.println("C"));
s.close(); // prints C
On the other hand, AutoCloseable interface (which BaseStream extends) encourages idempotent close() method. I propose the following change:
* BaseStream.onClose() implementation (AbstractPipeline.onClose()) must throw IllegalStateException if the stream is already linked or consumed.
* The documentation for BaseStream.onClose() should state that implementation may throw IllegalStateException if terminal operation is already called or stream is already closed.
* BaseStream.close() implementation must do nothing if called the second time.