Как можно добавить Integer в String ArrayList?

List list = new ArrayList<String>() ;
list.add(1) ;
Integer hello = (Integer) list.get(0) ;
System.out.println(hello);

В приведенном выше коде есть ссылка типа Список, ссылающегося на экземпляр ArrayList типа Строка. Когда выполняется строка list.add(1), не 1, добавленный в ArrayList (типа String)? Если да, то почему это разрешено?

Ответ 1

Вы использовали стирание типа, что означает, что вы проигнорировали ранее установленные общие проверки. Вы можете избавиться от этого, поскольку это, поскольку generics - это функция времени компиляции, которая не проверяется во время выполнения.

Что у вас такое же, как

List list = new ArrayList() ;
list.add(1) ;
Integer hello = (Integer) list.get(0) ;
System.out.println(hello);

или

List<Integer> list = new ArrayList<Integer>() ;
list.add(1) ;
Integer hello = list.get(0); // generics add an implicit cast here
System.out.println(hello);

Если вы посмотрите на байт-код, сгенерированный компилятором, нет способа сказать разницу.

Интересно, что вы можете это сделать

List<String> strings = new ArrayList<String>();
@SuppressWarnings("unchecked");
List<Integer> ints = (List) strings;
ints.add(1);

System.out.println(strings); // ok
String s= strings.get(0); // throws a ClassCastException

Ответ 2

Проблема в том, что ваша переменная list имеет тип raw, и вы можете добавлять в этот список объекты любого типа. Чтобы решить проблему, просто объявите ее как list of String:

List<String> list = new ArrayList<String>() ;

Ответ 3

Он компилируется, потому что в объявлении List list используется необработанный тип List, а не связанный тип List<String>. Вторая строка компилируется, потому что ваша переменная List может принимать что угодно. Третья строка компилируется, потому что list.get(0) возвращает Object. В четвертой строке нет причин для отказа.

Случайно, ничто в скомпилированном коде не привело к тому, что целое число 1 было добавлено к String. Но вы не должны зависеть от этого. Если бы первая строка была правильной

List<String> list = new ArrayList<>();

ваша ошибка была бы поймана во время компиляции.

Ответ 4

Когда вы объявляете такой список: List list = new ArrayList<String>() ;

Вы используете то, что называется Raw Type. Это тип, который имеет общий тип типа, например List, но вы его не смогли его предоставить. Если вы проверите предупреждения компилятора, вы увидите, что это говорит вам об этом. Смешивание параметризованных типов с необработанными типами обычно считается ошибкой программирования. Это нормально:

List<String> list = new ArrayList<String>() ;

и это нормально (но устарело):

List list = new ArrayList();

Но следует избегать того, как вы его написали.

Проблема в том, что generics проверяются только во время компиляции, и вы сказали компилятору List, а не List<String>, поэтому он позволит вам поместить все, что вы хотите там! Тот факт, что правая сторона имеет параметр, на самом деле ничего не значит, это тип фактической ссылки, которая имеет значение для компилятора.

Ответ 5

List list = new ArrayList<String>() ; // WARNING!!!

Небезопасный список относится к безопасному ArrayList

list.add(1) ;  // WARNING!!!

Целое число (int 1, преобразованное в Integer, является Autoboxing), а не String, добавленное в список

Integer hello = (Integer) list.get(0) ;

Кастинг необходим, потому что небезопасный список может содержать что угодно.

System.out.println(hello);

Integer.toString() называется

Когда выполняется строка list.add(1), это не 1, добавленный в ArrayList (типа String)?

Да. Integer был добавлен в ArrayList, который должен содержать String.

Если да, то почему это разрешено?

Обратная совместимость. Java должна поддерживать общие коды.

Список списков; означает, что он небезопасен, поэтому вы можете делать с ним что-либо, и упомянутый ArrayList() должен это терпеть.

Мораль: Не игнорируйте предупреждения компилятора, в противном случае Integer может входить в ArrayList, который должен содержать строки.

Ответ 6

Да... 1 добавлен в Array, потому что Java, как и другие языки, реализует неявное (автоматическое) преобразование (литье) типов данных примитивов.

Дополнительная информация здесь Конверсии и рекламные акции

Ответ 7

Попробуйте это

List.add(Integer.toString(1));

Вы также можете попробовать это

List list = new ArrayList<Object>() ;

Если нет необходимости, чтобы арраист должен быть Arraylist String

Ответ 8

Нет, потому что Java видит 1 как целое. Сначала вам нужно будет преобразовать свой номер в качестве строки в Integer.toString(n)