3

In Java 8, IntStream.spliterator() is overridden from the base class to return type Spliterator.OfInt, which is a sub-interface providing methods that operate on an IntConsumer instead of a generic Consumer<Integer>.

But since Java 11 (and continuing with 17 and 20), IntStream inherits the base class spliterator() method which only returns a generic Spliterator<Integer>.

I believe the reason for these specialized primitive types is largely to avoid the expensive overhead of constant boxing and unboxing (see for example this SO answer). If so, then there is a performance hit for using Spliterator<Integer> rather than Spliterator.OfInt. Does anyone know why this specialization in IntStream was removed?

Dan R
  • 1,412
  • 11
  • 21
  • 1
    The [OpenJDK repository on GitHub](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/IntStream.java#L879) suggests that it still returns `Spliterator.OfInt`. Have you actually failed to compile code that expects `Spliterator.OfInt`, or just looked at the Javadoc? – Louis Wasserman Jun 20 '23 at 03:35
  • Interesting that JavaDocs say `spliterator` is inherited. That certainly isn't true on my copy of JDK 17. – Sweeper Jun 20 '23 at 03:36
  • @LouisWasserman well now I feel like up is down and black is white. How could there be such a discrepancy - isn't the javadoc generated from this source? (I also checked on [devdocs.io](https://devdocs.io/openjdk~11/java.base/java/util/stream/intstream) and same thing there.) – Dan R Jun 20 '23 at 03:48
  • Yes, but it seems that the Javadoc generated from the JDK doesn't include overridden methods in detail if they don't have their own Javadoc comment (which you can see `IntStream#spliterator()` does not from the source code link provided by Louis). It shows them in sections like "methods declared in ". I'm not sure why this is the case; I'm not an expert in the `javadoc` tool, but I can't seem to reproduce the behavior shown by the standard library's documentation. – Slaw Jun 20 '23 at 05:31
  • If you don't provide explicit Javadoc for an overridden method it just generates the basic information inherited from the parent method. – user207421 Jun 20 '23 at 06:48
  • 3
    Side effect of [JDK-8157000](https://bugs.openjdk.org/browse/JDK-8157000). The issue has been noticed already, see [JDK-8219147](https://bugs.openjdk.org/browse/JDK-8219147) but it seems it didn’t cover all cases. Maybe, generics complicated matters. See also [JDK-8296607](https://bugs.openjdk.org/browse/JDK-8296607). – Holger Jun 20 '23 at 07:25
  • Re _"the expensive overhead of constant boxing and unboxing"_ and the _"performance hit"_, you might want to look at this [recent and authoritative SO answer](https://stackoverflow.com/a/73336364/2985643). In particular, note from the final paragraph of that answer: _"...even if boxing happens, does it really matter? How many billion-billion boxing operations would it take for this to show up on your performance metrics?"_ – skomisa Jun 20 '23 at 08:00
  • 1
    Holger's comment finally let me reproduce the problem. Looks like the JDK generates its documentation with `--override-methods=summary`. That means an overridden method that does not provide its own Javadoc comment, nor changes the return type, will not be documented in detail. That makes sense. But it appears there's a bug, and the tool seems to have missed the fact that the discussed `spliterator()` method had its return type changed from `Spliterator` to `Spliterator.OfInt`. I wouldn't be surprised if this bug was simply the order they perform checks, as [cont.] – Slaw Jun 20 '23 at 20:24
  • [cont.] a `Spliterator.OfInt` is a `Spliterator`. That change is already documented in the class documentation, as `IntStream` is a `BaseStream`. So, why document it again in the method? But that ignores that `Spliterator.OfInt` is a covariant return type, thus the bug. – Slaw Jun 20 '23 at 20:27

0 Answers0