Почему этот Java-код не генерирует исключение?

Я возился со списками и добрался до этого кода (его часть основного):

List l1 = new ArrayList<Object>();
List l2 = new ArrayList<String>();
Object t = "a";
l1.add("a");
l2.add(t);
System.out.println(l1.equals(l2));
System.out.println(l2.get(0));

Динамический тип l2 — ArrayList(type:String) , но мне удалось добавить к нему объект. Более того, сказано, что списки равны. Я подумал, что, может быть, он каким-то образом передает его в String, но потом попробовал:

Object t = 9;

И это все еще работало. Почти уверен, что это как-то связано с тем, что список является необработанным типом, но все же я не могу понять, как я могу добавить объект в ArrayList (тип: String). Заранее спасибо.


person Bar    schedule 02.07.2016    source источник


Ответы (3)


Вы объявляете l2 как необработанный список. Таким образом, вы можете добавить элемент любого типа.

Что касается равенства списков l2 и l1, в документации метода equals для класса arraylist говорится:

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

.

person Mikhail Chibel    schedule 02.07.2016
comment
Являются ли l1 и l2 абсолютно одинаковыми, несмотря на то, что один из них реализован как ArrayList‹String›, а другой — как ArrayList‹Object›? Под абсолютно одинаковым я подразумеваю, что я могу добавить любой тип элемента к обоим. Что касается равенства - я не был уверен, что a как объект равен a как String. Я вспомнил, что equals Object возвращает true, если и только если ссылка указывает на один и тот же элемент, а когда типы разные, это маловероятно. - person Bar; 02.07.2016
comment
@Bar Как уже сказано в цитате из этого ответа, не имеет значения, как вы объявляете эти списки, если они содержат элементы equal, то они равны. "a" - это строка, не имеет значения, если вы присвоите ее переменной типа Object. И еще раз проверьте, что такое полиморфизм. - person Tom; 02.07.2016

Класс String является потомком класса Object, поэтому существует наследование объектов.

Вы не должны использовать "равно" с наследованием.

Подробнее здесь: Почему мне не следует использовать equals с наследованием?

person Simone C.    schedule 02.07.2016
comment
На самом деле типом t во время выполнения является String, поэтому сравниваются два объекта String. - person TomekK; 02.07.2016

Дело в том, что объект можно преобразовать обратно в строку либо с помощью явного преобразования (в данном случае я бы назвал это распаковкой, как в C#), либо с помощью Java-аналога метода ToString() в C#. В любом случае объект может быть успешно преобразован в строку, поэтому среда выполнения не будет жаловаться.

Если бы t было числом, преобразованным в объект, вы бы либо получили исключение, либо получили строковое представление этого числа.

Равенство списков должно быть переопределено для вызова метода .equals объектов в каждом списке.

person Paul Stelian    schedule 02.07.2016