Wildcards Generics - непонятная ошибка

164
22 сентября 2021, 15:10
public static void main(String []args) {
    List<?> intList2 = new ArrayList<Integer>();
    intList2.add(new Integer(10)); //компилятор выдает ошибку
    intList2.add(new Float(10.0f)); //тут компилятор тоже выдает ошибку
}

Интересно знать, а в чем причина ошибок? Если вторая ошибка хоть немного понятна, то первая вообще не понятна.

Доп. инфо: Я знаю, что

        1) "subtyping does not work for generic type parameters: you cannot
            assign a derived generic type parameter to a base type parameter." 
        2) "you can use a wildcard to indicate that it can match for any
            type. With List<?>, you mean that it is a List of any type—in 
            other words, you can say it is a “list of unknowns!”"

если что.

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

ошибка следующая

Warning:(30, 22) java: Integer(int) in java.lang.Integer has been deprecated
Error:(30, 17) java: no suitable method found for add(java.lang.Integer)
    method java.util.Collection.add(capture#1 of ?) is not applicable
      (argument mismatch; java.lang.Integer cannot be converted to capture#1 of ?)
    method java.util.List.add(capture#1 of ?) is not applicable
      (argument mismatch; java.lang.Integer cannot be converted to capture#1 of ?)
Warning:(31, 22) java: Float(float) in java.lang.Float has been deprecated
Error:(31, 17) java: no suitable method found for add(java.lang.Float)
    method java.util.Collection.add(capture#2 of ?) is not applicable
      (argument mismatch; java.lang.Float cannot be converted to capture#2 of ?)
    method java.util.List.add(capture#2 of ?) is not applicable
      (argument mismatch; java.lang.Float cannot be converted to capture#2 of ?)
Answer 1

Вы можете безопасно добавить в коллекцию параметризованную метасимвольным аргументом ? только null.Остальные добавления являются не безопасными. В вашем случае , вы пытаетесь добавить инстанс класса Integer в коллекцию с не известным типом.Эта коллекция может содержать любой тип данных - String , Number , Integer , Float и т.д.

List<?> list = new ArrayList<Integer>();
list.add(new Integer(33));
// Это добавление безопасно только для коллекции типизированной типом Number & Integer.
list.add(new Double(33.4d));
// Безопасно только для коллекции типа Number & Double
list.add(null);
// Безопасно для коллекции любого типа.

Вот какую проблему решает такое поведение обобщений.

Integer[] ints = new Integer[10];
Object[] objs = ints;
objs[0] = "Hello,World!"; // Exception ArrayStoreException will be thrown
objs[1] = 23.34;//The same exception

Хотя в java массивы коварианты - означает , что массив типа Integer является и массивом типа Object , это грозит исключением выше.В массив типа Integer не может быть добавлена строка или числа Double.Так само и с обобщениями.

Answer 2

Дженерики и вайлдкарды созданы не для вывода типов (автоматического определения типа в месте использования), а для проверки совместимости типов в момент компиляции. Компилятор не пытается вывести тип, он просто читает как есть и проверяет совместимость типов. <?>- обозначает какой-то неизвестный тип, Collection<?> - коллекция объектов неизвестного типа.

List<?> list = new ArrayList<Integer>();
list.add(new Integer(33));

Как читает это компилятор:

  1. Создать ArrayList для хранения объектов Integer.
  2. Создать ссылку на реализацию List хранящую объекты неизвестного типа.
  3. Присвоить к List содержащую объекты неизвестного типа ссылку на ArrayList содержащий объекты с типом Integer. Ошибки нет, ведь мы можем ссылаться на что-то конкретное как на непонятно что.
  4. Добавить Integer в реализацию List содержащую объекты неизвестного типа. Ошибка: нельзя передать Integer в List объектов неизвестного типа , типы могут оказаться не совместимы, ведь List<?> может ссылаться на ArrayList<String>.
READ ALSO
Прозрачность statusbar - Android, Java

Прозрачность statusbar - Android, Java

Как сделать так чтобы картинка как бы сливалась с баром? Возможно ли это? Я видел один ответ, но он не подходит вообщеМне надо чтобы просто...

88
Почему приложения нет в поиске?

Почему приложения нет в поиске?

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

145
Не закрывается приложение в Android 10

Не закрывается приложение в Android 10

Я закрываю приложение так

105
Android: Программный сброс входящего звонка

Android: Программный сброс входящего звонка

Приложение сбрасывает входящий звонок и сохраняет номер звонящегоВсе нормально работало, но появилась проблема на Samsung j3 (Android 7

72