Tom Tresansky Tom Tresansky - 4 months ago 19
Java Question

Pass zero-sized array, save allocation?

In this code sample from page 114 of The Well-Grounded Java Developer, the last line:

Update[] updates = lu.toArray(new Update[0]);


contains the note: Pass zero-sized array, save allocation

List<Update> lu = new ArrayList<Update>();
String text = "";
final Update.Builder ub = new Update.Builder();
final Author a = new Author("Tallulah");

for (int i=0; i<256; i++) {
text = text + "X";
long now = System.currentTimeMillis();
lu.add(ub.author(a).updateText(text).createTime(now).build());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}

Collections.shuffle(lu);
Update[] updates = lu.toArray(new Update[0]);


What allocation is this saving, exactly?

The javadoc for List#toArray(T[] a) mentions:


If the list fits in the specified array, it is returned therein.
Otherwise, a new array is allocated with the runtime type of the
specified array and the size of this list.


Which is what I remembered: if the array you pass to
toArray(T[] a)
can't fit everything in the list, a new array is allocated. Plainly, there are 256 elements in the list, which cannot fit in an array of size 0, therefore a new array must be allocated inside the method, right?

So is that note incorrect? Or is there something else it means?

Answer

Going off of @Andreas comment on the question, I think it is a typo, and should say:

Pass zero-sized array, safe allocation.

Because if you passed nothing to the method, you'll end up calling the List#toArray() no-argument overload!

This would return an Object[] (though it would contain nothing but Update instances) and would require changing the type of the updates variable, so the last line would become:

Object[] updates = lu.toArray();

And then every time you wanted to iterate over and use the elements in that array, you'd have to cast them to Update.

Supplying the array calls the List#toArray(T[] a) method, which returns a <T> T[]. This array is reified to know it is an array of Update instances.

So supplying an empty array of Updates results in an Update[] coming back from the toArray call, not an Object[]. This is a much more type-safe allocation! The word "save" in the note must be a typo!

...this consumed way too much mental effort. Will post link to this in the book's forums so they can correct it.

Comments