java: создание многомерного универсального массива
как сделать многомерный массив общих элементов в 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
что исправить?
(Я ожидаю, что люди рекомендуют использовать списки. Пожалуйста, объясните, как достичь этого с помощью матрицы.)
7 ответов
я смог сделать что-то вроде этого
@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) Array.newInstance(new A<String>("dummy").getClass(), 2, 3);
EDIT:
из предложения @dsg следующее пропускает создание временного объекта.
@SuppressWarnings("unchecked")
A<String>[][] array = (A<String>[][]) Array.newInstance(A.class, 2, 3);
или (из предложения @irreputable)
@SuppressWarnings("unchecked")
A<String>[][] array = new A[2][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 generics,"Java теория и практика: дженерики gotchas"
благодаря комментариям я смог собрать воедино решение.
как мы видели, A<String>[][] array = new A<String>[2][3];
не работает.
вот как построить 2x3
массив A<String>
объекты, работает:
// 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);
почему бы вам не сделать что-то вроде этого: (non-generic)
String[][] non_generic_array = new String[][];
и сделать класс утилиты для реализации функций, которые вы сделали в A<T>
(как я полагаю, есть). Например:
когда у вас было это в 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
}
}
Хм, я думал, что массивы Java (начиная с Java 6) не поддерживают обобщения. Один из моих самых больших "wtf", когда я начал программировать с дженериками на 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];
}
выход:
класс java.ленг.Строка
привет