Skip to main content

Arrays.copyOf

5 replies [Last post]
mcnepp
Offline
Joined: 2005-06-22

I've just noticed the new methods in java.util.Arrays

There is one with the signature
public static T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType)

Can anyone explain why it was decided to specify the target type as the array type instead of the component type?
Wouldn't the latter be more natural?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
forax
Offline
Joined: 2004-10-07

good question,

If i understood, you propose to change the signature
of copyOf to this one:

public static T[] copyOf(U[] original, int newLength, Class newType)

The difference is that with the actual signature
you can't pass as argument of newType
an array of primitive values.

Rémi Forax

mcnepp
Offline
Joined: 2005-06-22

> The difference is that with the actual signature
> you can't pass as argument of newType
> an array of primitive values.

Good point, I hadn't thought about that. So this little "trick" rules out [i]one[/i] possible cause for a runtime exception. I'd buy it then, if this guaranteed type-safety in the usual generic meaning (method never throws if it compiles warning-free).
But unfortunately, this is not the case (and it was obviously not intented, guessing from the documentation).

jrose
Offline
Joined: 2004-11-29

Arrays.copyOf takes Class newType instead of Class newComponentType in order to support Collections.toArray(T[]) more directly. You can always convert between T[].class and T.class; the question is which use cases to support more conveniently. The signature of copyOf favors use cases where a template array (type T[]) is ready at hand:

T[] toArray(T[] a) {
... return (T[]) Arrays.copyOf(this.data, this.size, a.getClass());
...
}

as opposed to: copyOf(d,s,a.getClass().getComponentType())

Also, it turns out to be easier to optimize copyOf if it takes the actual array type, rather than the component type. One of the reasons for introducing the various versions of copyOf is to make it easier to optimize bulk array copies in application code.

mcnepp
Offline
Joined: 2005-06-22

> Arrays.copyOf takes Class newType
> instead of Class newComponentType in
> order to support Collections.toArray(T[]) more
> directly. You can always convert between T[].class
> and T.class; the question is which use cases to
> support more conveniently. The signature of copyOf
> favors use cases where a template array (type T[]) is
> ready at hand:

Thanks for the explanation. I can see now that both method signatures seem to have their benefits, so either of them is a reasonable choice.

> T[] toArray(T[] a) {
> ... return (T[]) Arrays.copyOf(this.data, this.size,
> a.getClass());
> ...
> }

But this is interesting: One cannot implement a generic [b]toArray[/b] by means of [b]copyOf[/b] without a gratuitous (unchecked) cast to [b]T[][/b].
This is because - quoting the JavaDoc for [b]Object.getClasS()[/b] - [i]The result is of type Class where X is [b]the erasure[/b] of the static type of the expression on which getClass is called.
[/i]
I'll post a new message, asking why that particular restriction was made!

mcnepp
Offline
Joined: 2005-06-22

> I'll post a new message, asking why that particular
> restriction was made!

Just for the curious few:
http://forum.java.sun.com/thread.jspa?threadID=746973