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.