java: multidimensional generic array creation
How do I make a multidimensional array of generic items in java?
Consider the class:
class A<T>
{开发者_运维知识库
T t;
public A(T t) { this.t = t; }
}
When I try to create a multidimensional array:
A<String>[][] array = new A<String>[2][3];
I get the following error:
generic array creation
A<String>[][] array = new A<String>[2][3];
^
I tried the following:
A<String>[][] array = (A<String>[][]) (new Object[2]3]);
But that just throws: java.lang.ClassCastException
What's the fix?
(I anticipate people recommending to use lists. Please explain how to achieve this using arrays.)
I was able to do something like this
@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) Array.newInstance(new A<String>("dummy").getClass(), 2, 3);
EDIT:
from @dsg's suggestion the following skips the creation of a temporary object.
@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) Array.newInstance(A.class, 2, 3);
or (from @irreputable's suggestion)
@SuppressWarnings("unchecked")
A<String>[][] array = new A[2][3];
You can't create an array of type-specific generic in simple way.
List<String>[] list = new List<String>[2]; //Illegal
List<?> aa[] = new List<?>[2]; // OK
...
A<?>[][] array = new A<?>[2][3]; // OK
A[0][0] = new A<String>(...);
This is an interesting article about Java 1.5 generics, "Java theory and practice: Generics gotchas"
Thanks to the comments I was able to piece together a solution.
As we saw, A<String>[][] array = new A<String>[2][3];
does not work.
Here how to construct a 2x3
array of A<String>
objects that does work:
// get the class of the basic object
Class c = new A<String>("t").getClass();
// get the class of the inner array
A<String>[] a0 = (A<String>[]) java.lang.reflect.Array.newInstance(c, 0);
// construct the outer array
A<String>[][] array = (A<String>[][]) java.lang.reflect.Array.newInstance(a0.getClass(), 2);
// fill it with instances of the inner array
for (int i = 0; i < 2; ++ i)
{
array[i] = (A<String>[]) java.lang.reflect.Array.newInstance(c, 3);
}
A much cleaner version (Thanks, @Balla R):
@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) java.lang.reflect.Array.newInstance(A.class,2,3);
new A[][]
and cast it to A<String>[][]
Why don't you do something like this: (non-generic)
String[][] non_generic_array = new String[][];
And make a utility class to implement the functions you made in A<T>
(as I suppose there are). Eg:
When you had this in A
:
public class A<T>
{
T obj;
public A(T obj) { this.obj = obj; }
public void someFunction() { ... }
}
You can make a utility class:
public class AUtils
{
public static <T> void someFunction(T obj)
{
// Here your code, applied to obj
}
}
Hmm, I thought Java Arrays (as of Java 6) didn't support generics. One of my biggest "wtf" when I started programming with generics in java.
class A<T>
{
T s;
public A(T t)
{
s = t;
}
public String getType()
{
return s.getClass().toString();
}
public T getThing()
{
return s;
}
}
public static void main(String[] args)
{
A<?>[][] a = new A<?>[2][3];
a[0][1] = new A<String>("hi");
System.out.println(a[0][1].getType());
System.out.println(a[0][1].getThing());
A<String> b = (A<String>) a[0][1];
}
output:
class java.lang.String
hi
精彩评论