【问题标题】:java: multidimensional generic array creationjava:创建多维泛型数组
【发布时间】:2011-07-23 15:51:50
【问题描述】:

如何在 java 中创建多维通用项数组?

考虑类:

class A<T>
  {
    T t;
    public A(T t) { this.t = t; }
  }

当我尝试创建一个多维数组时:

A<String>[][] array = new A<String>[2][3];

我收到以下错误:

generic array creation
A<String>[][] array = new A<String>[2][3];
                      ^

我尝试了以下方法:

A<String>[][] array = (A<String>[][]) (new Object[2]3]);

但这只是抛出:java.lang.ClassCastException

解决方法是什么?

(我预计人们会推荐使用列表。请解释如何使用数组来实现这一点。)

【问题讨论】:

  • 你坚持使用数组而不是其他集合类型的原因是什么?
  • 您正在将 Object[][] 转换为 A[][],两者不兼容。
  • @Gareth McCaughan -- 数组比列表更容易索引。 array[i][j]array.get(i).get(j) 更易读。当您编写复杂的算法时,这真的很有帮助。

标签: java arrays generics multidimensional-array


【解决方案1】:

我可以做这样的事情

    @SuppressWarnings("unchecked") 
    A<String>[][] array = (A<String>[][]) Array.newInstance(new A<String>("dummy").getClass(), 2, 3);

编辑:

根据@dsg 的建议,以下内容跳过了临时对象的创建。

    @SuppressWarnings("unchecked") 
    A<String>[][] array = (A<String>[][]) Array.newInstance(A.class, 2, 3);

或(来自@irreputable 的建议)

 @SuppressWarnings("unchecked")
 A<String>[][] array = new A[2][3];

【讨论】:

  • 我相信以下方法也有效:` @SuppressWarnings("unchecked") A[][] array = (A[][]) java.lang.reflect.Array .newInstance(A.class,2,3);`
  • @dsg 你们非常有趣。 Array.newInstance(A.class, 2, 3)new A[2][3] 完全相同
【解决方案2】:

感谢 cmets,我能够拼凑出一个解决方案。

正如我们所见,A&lt;String&gt;[][] array = new A&lt;String&gt;[2][3]; 不起作用。

这里如何构造一个 2x3 有效的 A&lt;String&gt; 对象数组:

// 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); 
}

更简洁的版本(感谢@Balla R):

@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) java.lang.reflect.Array.newInstance(A.class,2,3);

【讨论】:

  • 有没有办法在不实例化的情况下获取基本对象的类?
  • 虽然我很高兴你明白了这一点,但迫切的问题仍然是,为什么要为使用 ArrayList&lt;ArrayList&lt;A&lt;String&gt;&gt;&gt; 带来这么多麻烦?
  • 不,这就是问题所在。在实例化它之前,没有办法确定它的类型。看我的回答,你可以使用A&lt;?&gt;[][]作为你的数组。
【解决方案3】:

您不能以简单的方式创建特定类型的泛型数组。

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>(...);

这是一篇关于 Java 1.5 泛型的有趣文章,“Java theory and practice: Generics gotchas

【讨论】:

  • 这太酷了!我想你可以做A&lt;String&gt;[][] array = (A&lt;String&gt;[][]) new A&lt;?&gt;[2][3];
  • 是的,但是通过这种方式,您将收到未经检查的演员表警告,以防止它添加 @SuppressWarnings("unchecked")
【解决方案4】:

嗯,我认为 Java 数组(从 Java 6 开始)不支持泛型。当我开始在 java 中使用泛型编程时,我最大的“wtf”之一。

【讨论】:

    【解决方案5】:

    你为什么不做这样的事情:(非泛型)

    String[][] non_generic_array = new String[][];
    

    并创建一个实用程序类来实现您在A&lt;T&gt; 中创建的功能(我想有)。例如:

    当您在A 收到此消息时:

    public class A<T>
    {
        T obj;
        public A(T obj) { this.obj = obj; }
    
        public void someFunction() { ... }
    }
    

    你可以创建一个实用类:

    public class AUtils
    {
    
        public static <T> void someFunction(T obj)
        {
            // Here your code, applied to obj
        }
    
    }
    

    【讨论】:

      【解决方案6】:

      new A[][] 并将其转换为 A&lt;String&gt;[][]

      【讨论】:

        【解决方案7】:
        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];
        }
        

        输出:

        类 java.lang.String

        【讨论】:

          猜你喜欢
          • 2011-04-29
          • 1970-01-01
          • 1970-01-01
          • 2011-10-27
          • 1970-01-01
          • 1970-01-01
          • 2011-07-22
          • 1970-01-01
          相关资源
          最近更新 更多