Returning T[] (where T is Byte[]) to Byte[]

arrays, generics, java, java-6

Solution

A "generic" array can be constructed via reflection:

T[] array = (T[]) Array.newInstance(Byte.class, 32)

Replace `Byte.class` by a reference to the desired class. In other words:

public class TestClass<T> {
    T[] array;

    @SuppressWarnings("unchecked")
    public TestClass(Class<T> type) {
        array = (T[]) Array.newInstance(type, 32);
    }

    public T[] getArray() {
        return array;
    }

    public boolean doThing() {
        T[] t = array;

        return t == array && t != null;
    }
}

You can verify this as such:

public static void main(String[] args) {
    TestClass<Byte> test = new TestClass<Byte>(Byte.class);
    // No ClassCastException here
    Byte[] array = test.getArray();
    System.out.println(Arrays.asList(array));
}

Due to type erasure, you cannot solve this problem without resorting to a `Class<?>` object as a constructor argument.

Problem

I have a Java JUnit 4 test and a generic class which creates a generic array. When I create a method to return this generic array I get an error message upon returning it. It works if I return an ArrayList (where T is Byte by class instantiation) to an ArrayList. Why is it that the array appears to be instantiated and usable (tested on more complex classes) yet I can't return a reference to that array? Error: ``` java.lang.ClassCastException: [Lcom.waikato.assignment.Object; cannot be cast to [Ljava.lang.Byte; at com.waikato.testing.TestJava.test(TestJava.java:20) ``` Class: ``` public class TestClass<T> { T[] array; @SuppressWarnings("unchecked") public TestClass() { array = (T[]) new Object[32]; } public T[] getArray() { return array; } public boolean doThing() { T[] t = array; return t == array && t != null; } } ``` Test: ``` public class TestJava { @Test public void test() { TestClass<Byte> t = new TestClass<Byte>(); Byte[] b = t.getArray(); // Crash caused assertTrue(t.doThing()); // Works when above line is removed. assertTrue(b.length != 0); } } ```

Original source