The signature of the proposed generator is

public <T> T[] toArray(IntFunction<T[]> generator)

So I don't think that anything has really changed in this regard; T
can still be unrelated to E.

Right, the new method doesn't offer any safety compared to toArray(T[]). You can still get ArrayStoreException if T is incompatible with E. That's in part what led me to update the @throws ArrayStoreException text, since the previous text was basically wrong. But fundamentally the problem is unchanged.

There's a related enhancement request

    https://bugs.openjdk.java.net/browse/JDK-7023484
add typesafe static Collections.toArray(Collection<? extends T>, IntFunction<T[]>)

that would provide static type safety for this operation. Unclear whether it's worthwhile to add something like this, though.

That said, sending in a constant String[0] is probably just as good as
a generator, or better (in my naive estimation the tradeoff is a >0
comparison versus an interface method dispatch), than an i -> new
String[i] unless some kind of benchmark would appear which disproves
that hypothesis.

I did some quick benchmarking, and it looks like String[]::new is a shade faster (heh) than new String[size], but not quite as fast as new String[0]. But take these results with a grain of salt. I was doing the benchmarking on my laptop with my entire environment running, and I was also measuring my development fastdebug build. I wasn't able to see the same difference between new String[size] and new String[0] that Shipilëv observed.[1] It would be interesting to get some rigorous benchmarks to compare these, but I haven't yet taken the time to do this.

I don't think the main point of this is performance, though. I think the new preferred way to create an array of a particular type should be toArray(Foo[]::new), which is preferable to toArray(new Foo[0]) or toArray(EMPTY_FOO_ARRAY). I suppose those of us "in the know" would recognize toArray(new Foo[0]) to be idiomatic. But to understand it, you have to fully understand the semantics of toArray(T[]), and you have to have read Shipilëv's article to understand why creating an apparently wasted zero-sized array is (usually) the right thing. That seems pretty obscure.

s'marks


[1] https://shipilev.net/blog/2016/arrays-wisdom-ancients/

Reply via email to