mirror of
https://github.com/github/codeql.git
synced 2026-01-15 23:44:47 +01:00
62 lines
2.7 KiB
XML
62 lines
2.7 KiB
XML
<!DOCTYPE qhelp PUBLIC
|
|
"-//Semmle//qhelp//EN"
|
|
"qhelp.dtd">
|
|
<qhelp>
|
|
|
|
|
|
<overview>
|
|
<p>The <code>java.util.Collection</code> interface provides a <code>toArray</code>
|
|
method that can be used to convert a collection of objects into an array of a particular
|
|
type. This method takes an array as an argument, which is used for two purposes.
|
|
Firstly, it determines the type of the returned array. Secondly, if it is big enough to
|
|
hold all values in the collection, it is filled with those values and returned;
|
|
otherwise, a new array of sufficient size and the appropriate type is allocated and
|
|
filled.</p>
|
|
|
|
<p>It is common to pass a fresh zero-length array to <code>toArray</code>,
|
|
simply because it is easy to construct one. Unfortunately, this allocation is wasteful,
|
|
because the array clearly is not big enough to hold the elements of the collection. This can cause
|
|
considerable garbage collector churn, impacting performance.</p>
|
|
|
|
</overview>
|
|
<recommendation>
|
|
|
|
<p>There are at least two ways to address this issue.</p>
|
|
|
|
<p>The first is to always call <code>toArray</code> with a new array allocated with a
|
|
sufficient size to hold the contents of the collection. Usually, this involves calling
|
|
the collection's <code>size</code> method and allocating an array with that many
|
|
elements. While it may seem odd that adding a call to <code>size</code> improves performance, if you
|
|
do not pass a large enough array, the <code>toArray</code> method makes this call automatically.
|
|
Calling <code>size</code> explicitly and then calling <code>toArray</code> with a large enough array
|
|
avoids the possible creation of two arrays (one too small and consequently unused).</p>
|
|
|
|
<p>The second approach is to add a static field holding a constant zero-length array to the
|
|
enclosing class, and pass that field to <code>toArray</code>. In this case, <code>toArray</code>
|
|
will end up allocating a new array in (almost) every case, but because the same zero-length array
|
|
is reused every time, there is almost no overhead. (Note that if <code>toArray</code>
|
|
is invoked on an empty collection, it will return the passed-in array. If your code expects
|
|
a new array from every invocation of <code>toArray</code>, you should use the first method.)</p>
|
|
|
|
</recommendation>
|
|
<example>
|
|
|
|
<p>In the following example, the first version of class <code>Company</code> uses an inefficient
|
|
call to <code>toArray</code> by passing a zero-length array. The second and third version
|
|
illustrate the two ways of addressing this issue outlined above.</p>
|
|
|
|
<sample src="InefficientToArray.java" />
|
|
|
|
</example>
|
|
<references>
|
|
|
|
|
|
<li>
|
|
Java Platform, Standard Edition 6, API Specification:
|
|
<a href="http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#toArray%28T[]%29">toArray</a>.
|
|
</li>
|
|
|
|
|
|
</references>
|
|
</qhelp>
|