2014-09-22 4 views
3

Я попытался создать двухмерный общий массив в java. Я не получаю ошибки компиляции, но я получаю исключение при выполнении кода:Инициализация двумерного генераторного массива

Exception in thread "main" java.lang.ClassCastException: Cannot cast [[[Ljava.lang.String; to [[Ljava.lang.String; 
at java.lang.Class.cast(Unknown Source) 
at Tabela.<init>(Tabela.java:8) 
at TabelaTest.main(TabelaTest.java:4) 

Вот код:

import java.lang.reflect.Array; 

public class Tabela<T> { 

    private T[][] data; 

    public Tabela(Class<T[][]> c,int sizeX, int sizeY) { 
     this.data = c.cast(Array.newInstance(c.getComponentType(), sizeX, sizeY)); 
    } 

    public void setInfoAt(T info, int x, int y) { 
     this.data[x][y] = info; 
    } 
    public T getObjectAt(int x, int y) { 
     return this.data[x][y]; 
    } 
} 

public class TabelaTest { 

    public static void main(String args[]) { 
     Tabela<String> tabela = new Tabela<String>(String[][].class, 2, 2); 

     tabela.setInfoAt("a", 0, 0); 
     tabela.setInfoAt("b", 0, 1); 
     tabela.setInfoAt("c", 1, 0); 
     tabela.setInfoAt("d", 1, 1); 

     System.out.println(tabela.getObjectAt(1, 0)); 
    } 
} 

Похоже, я не могу использовать этот метод для двумерных массивов.

EDIT:

Используя метод из unholysampler он работает сейчас. Конструктор был изменен на:

public Tabela(Class<T> c,int sizeX, int sizeY) { 
    this.data = (T[][])Array.newInstance(c, sizeX, sizeY); 
} 

Дело в том, что затмение продолжает предупредив меня об этом гипсе (T [] []). Я могу это подавить, но нормально ли игнорировать?

ответ

5

Если вы посмотрите на сообщении об ошибке, вы увидите, что количество квадратных скобок отличаются.

Cannot cast [[[Ljava.lang.String; to [[Ljava.lang.String; 
      ---      -- 

Вы в конечном итоге с дополнительным уровнем массива из-за того, как вы звоните Array.newInstance(). Если вы хотите просто создать String массив, вы должны использовать:

String[] arr = (String[])Array.newInstance(String.class, 5); 

Обратите внимание, что вы передаете типа базового класса и метод «добавляет» слой скобок. Ваш звонок говорит, что вам нужен массив, содержащий экземпляры 2D-массивов String. Вместо этого вы хотите просто просто перейти в базовый класс, а затем указать размеры.

Array.newInstance(String.class, sizeX, sizeY); 
+0

Извините, но я действительно не понял. Насколько я понимаю, вы говорите, что мне нужно вызвать Array.newInstance только с T вместо T [] []? – lhahn

+0

Да. Поскольку Array.newInstance выполняет работу по созданию 2D-массива для вас. – NoDataFound

+0

спасибо, теперь это сработало – lhahn

1

Javadoc из Array#newInstance(..) заявляет

Если componentType представляет класс массива, число измерений нового массива равна сумме dimensions.length и числа измерений componentType. В этом случае тип нового массива - это тип компонента componentType.

Поскольку componentType является String[], класс массива, число измерений становится суммой dimensions.length, 2, а число измерений componentType, 1, в общей сложности 3.

Ваш звонок

Array.newInstance(c.getComponentType(), sizeX, sizeY) 

становится эквивалентным

new String[2][2][] 

Вы можете, вместо этого, вызовите метод newInstance(Class, int) в

Array.newInstance(c.getComponentType(), sizeX) 

создать

new String[2][] 

но вам придется создавать экземпляры вложенных массивов вручную.

Или реорганизовать параметры вашего конструктора для реализации unholysampler's solution.

2

Эта ошибка в конструкторе:

public Tabela(Class<T[][]> c,int sizeX, int sizeY) { 
     this.data = c.cast(Array.newInstance(c.getComponentType(), sizeX, sizeY)); 
} 
  • c.getComponentType() фактически T[].
  • Array.newInstance(Class, int...) вернуть массив такого размера, как в массиве. Вы передаете два значения, массив является двухмерным.

    Array.newInstance(
        c.getComponentType(), // returns T[] 
        sizeX, sizeY 
    ) // returns T[][][] 
    

который был бы во время выполнения, эквивалентную new T[sizeX][sizeY][], если бы это было возможно (тип стирания).

Я хотел бы сделать что:

public Tabela(Class<T> c,int sizeX, int sizeY) { 
     this.data = Array.newInstance(c, sizeX, sizeY); 
} 
Смежные вопросы