开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜