Универсальные массивы в Java

Шестнадцатеричный класс в кодеке свободного городского населения должен сделать это для Вас.

http://commons.apache.org/codec/

import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF

44
задан Peter Mortensen 9 May 2013 в 20:29
поделиться

4 ответа

Дженерики и массивы в принципе несовместимы. Короткий ответ: эту проблему можно обойти. Более длинный ответ заключается в том, что вам, вероятно, не следует, и я объясню почему.

Вы можете использовать Array.newInstance () следующим образом:

private Comparable[] hashtable;

...

hashtable = (Comparable[])Array.newInstance(Comparable.class, tableSize);

, но вы не можете создать массив параметризованного типа

Массивы ковариантны . Это означает, что они сохраняют тип своих элементов во время выполнения. Дженерики Java - нет. Они используют стирание типа , чтобы в основном замаскировать происходящее неявное приведение типов. Это важно понимать.

Итак, когда вы создаете массив Object, вы не можете преобразовать его, скажем, в массив Comparable (или любой другой тип), потому что это неверно.

Чтобы дать вам пример. С дженериками это совершенно законно:

List<String> list = new ArrayList<String>();
List<Integer> list2 = (List<Integer>)list;
list.add(3);

Это также то, почему вы не можете этого сделать:

public <T> T newInstance(T t) {
  return new T(); // error!
}

т.е. во время выполнения нет сведений о классе T. Вот почему приведенный выше код чаще записывается как:

public <T> T newInstance(T t, Class<T> clazz) {
  return clazz.newInstance();
}

, потому что они не являются типом времени выполнения для универсального аргумента. Но с массивами:

String arr[] = new String[10];
Integer arr2[] = (Integer[])arr; // error!

В этом случае (imho) вам следует делать не массивы, а использовать ArrayList . Честно говоря, очень мало причин использовать массивы вместо ArrayList , и обобщения - лишь один из примеров этого.

Для лучшего и более полного объяснения см. (Превосходные) Java Generics FAQ : массив ссылок на супертипы - это супертип массива подтипа Ссылки. То есть Объект [] является супертип String [] и строка к массиву можно получить доступ через ссылочная переменная типа Object [] .

...

78
ответ дан 26 November 2019 в 21:56
поделиться

Приведение, которое вы пытаетесь выполнить

(T[])(new Object[tableSize]);

, завершается неудачно, поскольку элементы в массиве являются экземплярами Object. Объект не расширяется Comparable , поэтому приведение (T []) не выполняется, потому что T определяется как:

T extends Comparable<String>

Чтобы решить эту проблему, либо:

  • Создайте экземпляр массива, чтобы его элементы были экземпляры некоторого класса, который расширяет Comparable
  • Измените hashTable с массива (который не является универсальным типом) на общий тип коллекции, например List
16
ответ дан 26 November 2019 в 21:56
поделиться

Вы часто сталкиваетесь с проблемами, когда вам нужно создать что-то общего типа. Самый простой способ обойти это - передать класс, который фактически будет храниться в конструкторе. Таким образом, вы можете построить из фактического типа. Попробуйте что-то вроде этого:

public class Hash<T extends Comparable<String>>
{
  Hash(int records, double load, Class<T> class)
  {
    tableSize = (int)(records / loadFactor);
    tableSize = findNextPrime(tableSize);

    hashTable = java.lang.reflect.Array.newInstance(class, tableSize);
  }

private T[] hashTable;
private int tableSize;

}
1
ответ дан 26 November 2019 в 21:56
поделиться

Приведение, которое вы пытаетесь выполнить

(T[])(new Object[tableSize]);

, терпит неудачу, потому что элементы в массиве являются экземплярами Object. Объект не расширяет Comparable , поэтому приведение (T []) не выполняется, потому что T определяется как:

T extends Comparable<String>

Чтобы решить эту проблему, либо:

  • Создайте экземпляр массива, чтобы он ' Элементы s являются экземплярами некоторого класса, который расширяет Comparable
  • Изменение hashTable с массива (который не является универсальным типом) на общий тип коллекции, например List hashTable = new ArrayList (tableSize>)
4
ответ дан 26 November 2019 в 21:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: