Как я использую массивы универсальных типов правильно?

Как насчет получения версии системного файла?

Лучшим файлом будет kernel32.dll, расположенный в% WINDIR% \ System32 \ kernel32.dll.

Существуют API для получения версии файла. Например: я использую Windows XP -> «5.1.2600.5512 (xpsp.080413-2111)»

19
задан Hanno Fietz 22 May 2009 в 10:42
поделиться

5 ответов

Java не позволяет универсальные массивы . Дополнительная информация в FAQ по Java Generics .

Чтобы ответить на ваш вопрос, думать о коллекциях как о абстракция массивов, у них есть специальные свойства, которые делают коллекции не. Массивы на языке Java ковариантный - что означает, что если Целое число расширяет число (которое делает), то не только Целое число также число, но целое [] является также номер [] , и вы можете передать или присвоить целое число [] , где Требуется номер [] . (Больше формально, если Число является супертипом of Целое число , тогда Число [] является супертип Integer [] .) Вы можете думаю, то же самое верно и для универсальных типы также - это List является супертипом List , и что вы можете передать List где ожидается список List . К сожалению, это не работает

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

 List  li = new ArrayList  ();
Список <Число> ln = li; // незаконно
ln.add (новый Float (3.1415));

Поскольку ln является List , добавление a Float ему кажется совершенно законным. Но если бы ln было наложено на li, тогда это нарушит обещание безопасности типов подразумевается в определении li - что это список целых чисел, который вот почему общие типы не могут быть ковариантный.

30
ответ дан 30 November 2019 в 03:25
поделиться

Клетус правильно сказал. Существует общее несоответствие между обычно принудительной инвариантностью параметров универсального типа и ковариацией массивов Java.

(Некоторая предыстория: дисперсия определяет, как типы связаны друг с другом в отношении подтипов. Т.е. Сбор <: Сбор не удерживается. Итак, что касается системы типов Java, коллекция String не является коллекцией CharSequence. Ковариантность массивов означает, что для любых типов T и U с T <: U, T [] <: U []. Итак, вы можете сохранить переменную типа T [] в переменную типа U []. Поскольку существует естественная потребность в других формах дисперсии, Java, по крайней мере, допускает использование подстановочных знаков для этих целей.)

Решение (на самом деле хак), которое я часто использую, - это объявление вспомогательного метода, который генерирует массив:

public static <T> T[] array(T...els){
    return els;
}
void test(){
    // warning here: Type safety : A generic array of Class is created for a varargs parameter
    Class<? extends CharSequence>[] classes = array(String.class,CharSequence.class);
}

Из-за стирания сгенерированные массивы всегда будут иметь тип Object [].

4
ответ дан 30 November 2019 в 03:25
поделиться

Массивы всегда относятся к определенному типу, в отличие от Коллекций до Generics.

Вместо

Class<? extends IMessage>[] _rgAccepted;

Вы следует просто написать

IMessage[] _rgAccepted;

Generics не входят в это.

1
ответ дан 30 November 2019 в 03:25
поделиться

И каков же тогда "правильный" (или, по крайней мере, распространенный) способ сделать это?

@SuppressWarnings(value="unchecked")
public <T> T[] of(Class<T> componentType, int size) {
    return (T[]) Array.newInstance(componentType, size);
}

public demo() {
    Integer[] a = of(Integer.class, 10);
    System.out.println(Arrays.toString(a));
}
3
ответ дан 30 November 2019 в 03:25
поделиться

IMHO,

this._rgAccepted = (Class<? extends IMessage>[])new Class[1];

- это подходящий способ справиться с этим. Типы компонентов массива должны быть реифицируемыми типами, и Class является наиболее близким реифицируемым типом к Class . Он будет работать так же, как вы ожидаете, что Class [] будет работать.

Да, технически он не отмечен и может вызвать проблемы позже, если вы приведете его к другому более общему типу массива и поместите в него неправильный материал, но поскольку это частное поле в вашем классе, я полагаю, вы можете убедиться, что оно используется надлежащим образом.

1
ответ дан 30 November 2019 в 03:25
поделиться
Другие вопросы по тегам:

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