ArrayList.addAll(ArrayList) выбрасывает НЕКОТОРЫЕ UnsupportedOperationException
У меня есть код, который читает список из некоторых вычисленных строковых данных. Что я не понимаю - почему исключение UnsupportedOperationException на addAll() и почему это случайное поведение?
Я знаю, что создание целевого массива ArrayList, а не добавление к возвращаемому, решает проблему, я ищу лучшего понимания, а не исправления.
List<Event> eventList = eventTable.getEvents(); // returns ArrayList
while (hasNextPage()) {
goToNextPage();
eventList.addAll(eventTable.getEvents());
}
Ответы
Ответ 1
List<Event>
не обязательно является ArrayList<Event>
. (Правда, наоборот).
Причина, по которой вы получаете UnsupportedOperationException
, иногда, потому что eventTable.getEvents()
иногда возвращает список, который поддерживает addAll
, а иногда и нет.
Реализация getEvents
может, например, выглядеть так:
if (noEventsAvailable) {
return Collections.emptyList();
} else {
List<Event> toReturn = new ArrayList<Event>();
// populate list...
return toReturn;
}
(В вашем комментарии вы пишете // returns ArrayList
. Я не знаю, откуда вы это взяли, но я точно знаю одно: ArrayList
всегда будет поддерживать операцию addAll
.)
Правильный способ решить это, как вы упомянули, сделать
List<Event> eventList = new ArrayList<Event>(eventTable.getEvents());
Ответ 2
Это зависит от фактической реализации List
.
Например, если базовый список был получен с помощью Collections.unmodifiableList(), то вызов addAll()
или любого другого метода модификации будет вызывать UnsupportedOperationException
.
Ответ 3
Когда он выдает исключение, он должен показать вам точный номер строки и файл исходного кода - вы должны точно узнать, почему он выбрасывает исключение.
Я предполагаю, что при определенных обстоятельствах eventTable.getEvents()
возвращает неизменный список или что-то в этом роде, но, не зная, что такое eventTable
, трудно сказать точно. Если вы можете создать короткую, но полную программу, которая демонстрирует проблему, это значительно облегчит диагностику.