почему Java допускает объявление универсального массива? - PullRequest
0 голосов
/ 22 июня 2019

Я знаю, что создание универсального массива массива недопустимо, поскольку массивам необходимо знать их тип во время выполнения, но, поскольку универсальные данные удаляют информацию о типе во время выполнения, создание универсального массива невозможно. Но почему это позволяет объявить универсальный массив следующим образом:

private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling

Ответы [ 2 ]

1 голос
/ 22 июня 2019
private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling
  • Ваш первый пример был оценкой времени компиляции, чтобы гарантировать типирование. Просто говорит, что этот массив может содержать что-то типа E.
  • Ваш второй пример должен быть выполнен во время выполнения, когда E имеет уже были стерты. Не удается создать массив типа E, так как E больше не доступен.

Разрешение объявлений универсального массива обеспечивает соответствие соответствующих типов во время компиляции.

      Integer[] ints1 = null;
      String[] str1 = null;

      // both requires cast or it won't compile
      Integer[] ints = (Integer[])doSomething1(ints1);
      String[] str = (String[])doSomething1(str1);

      //but that could result in a runtime error if miscast.
      //That type of error might not appear for a long time

      // Generic method caters to all array types.
      // no casting required.
      ints = doSomething2(ints1);
      str = doSomething2(str1);

   }

   public static Object[] doSomething1(Object[] array) {
      return array;
   }

   public static <T> T[] doSomething2(T[] array) {
      return array;
   }

Это позволяет примеры, такие как:

public <T> void copy(List<T> list, T[] array) {
   for (T e : array) {
      list.add(e);
   }
}

Затем можно присвоить значение из списка или массива некоторой переменной типа T, не получая исключение приведения класса или без проверки instanceof.

0 голосов
/ 22 июня 2019

Если E является формальным обобщением текущего класса, да, вы можете сделать это:

List<E> e = new ArrayList<E>();

, но вы не можете сделать это:

E[] e = new E[10];

Но объявив *Переменная 1008 * имеет смысл все равно.

, потому что никто не мешает вам оценить массив со стороны клиента, который знает реальный тип массива:

Foo<E> class{        
    private E[] array;
    Foo(E[] array) {
        this.array = array;
    }
}

И использовать его как:

Foo<String> foo = new Foo<>(new String[] { "a", "b" });

Или, в качестве альтернативы, вы можете также передать класс массива для создания экземпляров со стороны клиента:

Foo<String> foo = new Foo<>(String.class);

Итак, вы видите, что объявление E[] array не так беспомощно.

...