Вопрос-ответ

What's the reason I can't create generic array types in Java?

В чем причина, по которой я не могу создавать универсальные типы массивов в Java?

В чем причина, по которой Java не позволяет нам делать

private T[] elements = new T[initialCapacity];

Я мог бы понять, что .NET не позволяет нам этого делать, поскольку в .NET у вас есть типы значений, которые во время выполнения могут иметь разные размеры, но в Java все виды T будут ссылками на объекты, следовательно, имеющими одинаковый размер (поправьте меня, если я ошибаюсь).

В чем причина?

Переведено автоматически
Ответ 1

Это потому, что массивы Java (в отличие от универсальных) содержат во время выполнения информацию о типе своего компонента. Поэтому вы должны знать тип компонента при создании массива. Поскольку вы не знаете, что такое T во время выполнения, вы не можете создать массив.

Ответ 2

Цитата:


Массивы универсальных типов недопустимы, потому что они не являются надежными. Проблема связана с взаимодействием массивов Java, которые не являются статически надежными, но динамически проверяются, с универсальными массивами, которые являются статически надежными, но не проверяются динамически. Вот как вы могли бы воспользоваться этой лазейкой.:


class Box<T> {
final T x;
Box(T x) {
this.x = x;
}
}

class Loophole {
public static void main(String[] args) {
Box<String>[] bsa = new Box<String>[3];
Object[] oa = bsa;
oa[0] = new Box<Integer>(3); // error not caught by array store check
String s = bsa[0].x; // BOOM!
}
}

Мы предложили решить эту проблему
используя статически безопасные массивы
(также известные как Variance), но это было отклонено
для Tiger.


-- gafter


(Я полагаю, что это Нил Гафтер, но не уверен)

Смотрите это в контексте здесь: http://forums.sun.com/thread.jspa?threadID=457033&forumID=316

Ответ 3

Не в состоянии предоставить достойное решение, вы просто получаете что-то похуже, ИМХО.

Обычный способ обхода заключается в следующем.

T[] ts = new T[n];

заменяется на (при условии, что T расширяет объект, а не другой класс)

T[] ts = (T[]) new Object[n];

Я предпочитаю первый пример, однако более академические типы, похоже, предпочитают второй или просто предпочитают не думать об этом.

Большинство примеров того, почему вы не можете просто использовать Object [], в равной степени применимы к списку или коллекции (которые поддерживаются), поэтому я рассматриваю их как очень слабые аргументы.

Примечание: это одна из причин, по которой сама библиотека коллекций не компилируется без предупреждений. Если этот вариант использования не может поддерживаться без предупреждений, что-то фундаментально нарушено в модели generics, ИМХО.

Ответ 4

Причина, по которой это невозможно, заключается в том, что Java реализует свои универсальные типы исключительно на уровне компилятора, и для каждого класса создается только один файл класса. Это называется стиранием типов.

Во время выполнения скомпилированный класс должен обрабатывать все свои варианты использования одним и тем же байт-кодом. Таким образом, new T[capacity] не имел бы абсолютно никакого представления, какой тип необходимо создать.

java generics