Streams factories in Stream

John Rose john.r.rose at
Tue Apr 23 18:00:25 PDT 2013

On Apr 23, 2013, at 12:14 PM, Brian Goetz <brian.goetz at> wrote:

> You've already paid the cost of boxing the args into an empty array.

Yuck, that bugs me.  We can fix the zero-length cost by doing for zero-length arrays what we do for boxing conversion.

That is:

5.1.7 Boxing Conversion

... At run time, boxing conversion proceeds as follows:
... If p is a value of type int, then boxing conversion converts p into a reference r of class and type Integer, such that r.intValue() == p...
[NOTE: There is no "new" operator in the specification, just a guarantee that the implementation finds a suitable box for the value.]
... Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise...

The varargs boxing logic is here: Evaluate Arguments
... If the method being invoked is a variable arity method m, it necessarily has n > 0 formal parameters. The final formal parameter of m necessarily has type T[] for some T, and m is necessarily being invoked with k ≥ 0 actual argument expressions.

[INSERT] If m is being invoked with k = n-1 actual argument expressions, then the argument list (e1, ..., en-1) is evaluated as if it were written as (e1, ..., en-1, a0), where a0 is an array whose type is the erasure (§4.6) of T[] and whose length is zero.

If m is being invoked with k ≠ n actual argument expressions, or, if m is being invoked with k = n actual argument expressions and the type of the k'th argument expression is not assignment compatible with T[], then the argument list (e1, ..., en-1, en, ..., ek) is evaluated as if it were written as (e1, ..., en-1, new |T[]| { en, ..., ek }), where |T[]| denotes the erasure (§4.6) of T[].

The preceding paragraphs are crafted to handle the interaction of parameterized types and array types ...

[INSERT] They are also crafted to allow implementations to optimize the case of an empty argument array, by neither mandating nor forbidding the creation of a new array at runtime.

Either javac or the JVM or both could use this permission to remove the allocation cost for zero-length varargs.

— John

More information about the lambda-dev mailing list