Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8147505

BaseStream.onClose() should not allow registering new handlers after stream is consumed

XMLWordPrintable

      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.

            tvaleev Tagir Valeev
            tvaleev Tagir Valeev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: