Страницы

Поиск по вопросам

понедельник, 11 февраля 2019 г.

Как работает Arrays.toList (E … a)?

Есть код:
List c1 = new ArrayList<>( Arrays.asList(new Integer(1394), new Integer(52837)) ); List c2 = Arrays.asList(new Integer[c1.size()]);
Как мы вообще присваиваем c2 значение? На что мы ссылаемся, если Array.asList(T... a) возвращает List ? Я даже не понимаю, что это за странный тип возвращаемого значения. Мораль в том, что возвращается некоторый List, но List — это интерфейс. Значит, мы получим ссылку на объект, для которого определено действие .add(E o); Но почему-то вызов c2.add в данном случае вызывает ошибку. Почему так?


Ответ

Arrays.asList - возвращает список фиксированного размера. Поэтому нельзя ни добавлять, ни удалять. Чтобы как-то манипулировать элементами, придется оборачивать в новый список без фиксированного размера:
// List c2 = new ArrayList(Arrays.asList(new Integer[c1.size()])); List c2 = new LinkedList(Arrays.asList(new Integer[c1.size()]));

Если углубиться:
Во внутренностях метод Arrays.asList возвращает следующее:
return new ArrayList<>(a);
но(!!!) возвращает он ArrayList не тот, который находится в пакетеjava.util.ArrayList а тот, который определен как внутренний класс внутри самого java.util.Arrays;. Выглядит он так:
private static class ArrayList extends AbstractList implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; //.... и т.д. реализация }
Как видим, эта внутренняя реализация наследуется от AbstractList, в котором по дефолту определены некоторые методы в таком виде
public boolean add(E e) { add(size(), e); return true; }
public void add(int index, E element) { throw new UnsupportedOperationException(); }
public E remove(int index) { throw new UnsupportedOperationException(); }
Вот и получается, что вроде как вернули ArrayList, но на самом деле не тот лист, который ожидали (java.util.ArrayList), а эмуляцию.

О том, что такое и List стоит прочитать материалы на тему generics или обобщений. Тема очень широкая.

Комментариев нет:

Отправить комментарий