Arrays and Generics in Java do not mix very well. In order to create an array, you need to know the object class the array is supposed to store.

Arrays in Java are special: they can efficiently store primitive data types. The expected difference in efficiency between byte[] and Byte[] is pretty big (of course some good VM might optimize) for obvious reasons (think of: references, garbage collection, pointer sizes, …).

This is probably why you need to know the type before creating an array (because an array of primitive types such as byte will be different from one that stores objects of some kind).

In particular, the following Java code

  String[] foo = (String[]) new Object[0];

results in a run time error (“[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;”). But it gets more confusing when you introduce generics:

public static <T> T[] test() {
  T[] te = (T[]) new Object[0];
  System.err.println(te.length);
  return te;
}

String[] foobar = test();

will print “0”, then throw the same run time error in the foobar line.

What happens here is that in the test() method, T actually is replaced with “Object” at compile time. Thus the array type works just fine, and so does the call to te.length. Upon returning, it is then cast into a String[] array and fails.

Now here comes a crazy Java hack:

public static <T> T[] test(T... ts) {
  T[] te = (T[]) java.lang.reflect.Array.
      newInstance(ts.getClass().getComponentType(), 0);
  System.err.println(te.length);
  return te;
}

String[] foobar = test();

The exception is gone, foobar is of the proper type now!

A result of discovering this hack are these two methods:

public static <T> T[] newArrayOfNull(int len, T... ts) {
  // Varargs hack!
  return (T[]) java.lang.reflect.Array.
      newInstance(ts.getClass().getComponentType(), len);
}

public static <T> T[] toArray(Collection<T> coll, T... ts) {
  // Varargs hack!
  return coll.toArray(ts);
}

Notice how elegant the last method looks - and it finally allows you to do toArray(collection) instead of collection.toArray(new WhateverClassTheCollectionHas[0]).

Note that this is still a hack, and may or may not work with all Java compilers, JREs and/or Java versions.

Update: Note that this ‘hack’ is also not transitive. The context calling toArray needs to know the object type at compile time. So it doesn’t save you much more than writing “new KnownClass[0]” etc.

Update: So I’m actually not using this - it’s just a hack, and often quite hackish. The problem is that when you call e.g. toArray in an Generics context, it will actually create an array of “Object”, so it makes much more sense to verbosely specify the class you want to use for the arrays (and get some reliability in use back).