Generic array factory in Java: receipt for disaster

4 11 2010

Let’s implement a generic factory method for arrays in Java like this:

static <T> T[] createArray(T... t) {
    return t;

We can use this method to create any array. For example an array of strings:

String[] strings = createArray("some", "thing");

Now let’s add another twist:

static <T> T[] crash(T t) {
    return createArray(t);

String[] outch = crash("crash", "me"); 

Running this code will result in a ClassCastException on the last line:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

At first this seems strange. There is no cast anywhere here. So what is going on? Basically the Java compiler is lying at us: calling the crash method with string arguments, it tells us that we get back an array of strings. Now looking at the exception we see that this is not true. What we really get back is an array of objects!

Actually the Java compiler issues a warning on the createArray call in the crash method:

Type safety : A generic array of T is created for a varargs parameter

This is how it tells us about its lying: “Since I don’t know the actual type of T, I’ll just return an array of Object instead.” I thinks this is wrong. And others seem to think along the same lines.



6 responses

5 11 2010
Tweets that mention Generic array factory in Java: receipt for disaster « Michid’s Weblog --

[…] This post was mentioned on Twitter by Planet Scala, Planet Lang. Planet Lang said: [Scala] Generic array factory in Java: receipt for disaster: Let’s implement a generic factory method for arrays… […]

11 11 2010

Java arrays are covariant, so this should not be a surprise, *particularly* not when the compiler even warns you.
Now, we can agree that covariant arrays are bad, but that’s been the state of Java since 1.0

11 11 2010

This does not change my point: the compiler lies. At least it warns about its untruthfulness .

I understand that the issue at hand is an unfortunate interplay between covariant arrays, generic types and implementing varargs through arrays. But making the compiler lie seem plain wrong to me. That code should not compile at all!

8 03 2011

In Java, object arrays are currently covariant. Actually they are, but only when reading. To solve the problem, the ‘read’ and the ‘write’ type would need to be specified, so instead of (Object[] t) it would be (Object/String[] t) which means read objects, but store strings. This doesn’t solve the problem above however.

13 10 2014

this shows a better approach for creating generic arrays in Java. don’t use varargs as it can be fickle. Use the Class:

import java.lang.reflect.Array;

public static E[ ] genericArray( Class elementType, int capacity ) {
E[ ] gArray = null;
if( elementType != null && !elementType.isPrimitive() ) {
if( capacity < 0 ) {
capacity = 0;
gArray = (E[ ])Array.newInstance( elementType, capacity );
return gArray;

this works for everything except primitive arrays. Worst case it returns null, but it won't cause any run time exceptions.

13 10 2014

^the generic parameter int the first line for E got cut off
*after the static keyword should have the [greater than] E [less than]
*same with after Class

public static E[ ] genericArray( Class elementType, int capacity ) {

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: