2015-07-22 3 views
8

У меня есть кодКогда List.addAll() выбрасывает IllegalStateException?

private List<Field> subFields; 
private Collection<Field> subFieldsCollection; 

... 

try { 
    if (subFields == null && subFieldsCollection != null && !subFieldsCollection.isEmpty()) { 
     subFields = new ArrayList<>(); 
     subFields.addAll(subFieldsCollection); 
    } 
} catch (IllegalStateException e) { 
    ... 
} 

и мне интересно, как это может произойти за IllegalStateException быть выброшен. По-видимому, это случилось с пользователем моего приложения, но я не могу отслеживать, что было не так.

Документация Collection.addAll() говорит:

IllegalArgumentException - , если не все элементы могут быть добавлены в это время из-за вставки ограничения

Но каковы ограничения вставки?

Я думаю, это зависит от конкретного типа коллекции. Я использую ArrayList, так что давайте проверим документы для addAll() из List интерфейса:

IllegalArgumentException - если некоторое свойство элемента указанной коллекции не мешает ему быть добавлены в этот список

Ну, какое свойство элемента может помешать добавлению элемента в список? Мои обе коллекции одного типа, я должен иметь возможность добавлять нулевые значения.

Может кто-нибудь объяснить это мне, пожалуйста?

+0

Я просто стреляю в темноту здесь, но может ли это не быть связано с параллелизмом? – Mackiavelli

+0

Не совсем ясно, какая версия Java, которую вы используете, но исходный код для Java SE 6 никогда не выдает это исключение из 'addAll()' кроме косвенно при обращении к 'Collection'. Вы видели трассировку стека и уверены ли вы, что это исключение? – Persixty

+6

Пожалуйста, добавьте трассировку стека исключения в свой вопрос. – VGR

ответ

1

В зависимости от того, сколько информации у вас есть у пользователя, это может быть неопровержимо. Но я сделаю предположение и удалю свой ответ, если выяснится, что это противоречит этому. :)

Предполагая, что вы написали весь код, я согласен с тем, что addAll() не может выбрасывать IllegalStateException (и все разговоры о IllegalArgumentException не имеет значения).

Я предполагаю, что ошибка не исходит из вызова addAll(), а из другого вызова в коде (не показан), который пытается манипулировать одной из этих коллекций. Это is можно получить IllegalStateException, пытаясь, например, перебирать список (используя итератор, полученный с помощью .iterator()) и удалить элемент, а затем попытаться удалить другой элемент без вызова Iterator.next(). Аналогично, Iterator.set() может выбросить один в итераторе, полученный из ArrayList. Поэтому я предполагаю, что где-то в манипулировании списком происходит одна из этих вещей.

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

0

Мне неизвестны какие-либо реализации (в jre или любой библиотеке), которые вызывают исключение IllegalArgumentException.

Но вы можете легко создать свою собственную реализацию, которая выдает такое исключение. Интерфейс Collection информирует пользователей о том, что разработчик может использовать IllegalArgumentException - он не говорит, что разработчики actualy do используют его.

Пример:

import java.util.ArrayList; 


public class PickyList<T> extends ArrayList<T> { 

    public static class SpecialThing { 

    } 

    @Override 
    public boolean add(T e) { 
     if (e instanceof SpecialThing) 
      return super.add(e); 
     throw new IllegalArgumentException(); 
    } 

} 

В результате я бы рекомендовал этот подход:

  • проверить свой код, который вы добавляете семантический разумные элементов в вашу коллекцию. Не добавляйте объекты класса Person в список под названием postalCodes
  • обрабатывать любое исключение из технического режима в подходящим способом. Например отката транзакций, протоколирование, информирует пользователя и/или службу поддержки
  • считают информировать абонентов о вашем методе (через JavaDoc), что ваш метод может не
1

Ваш код не может бросить IllegalArgumentException, потому что ArrayList#addAll не может выбрасывать такое исключение.

Для того чтобы получить это исключение, вы должны использовать класс, реализующий Collection, в котором может быть выбрано такое исключение. Вы можете легко сделать свой собственный, расширив ArrayList и переопределив задействованные методы.

+1

Будущая реализация 'ArrayList # addAll' ** может ** вызывать' IllegalArgumentException' (т. Е. Следующую версию jre). Но, конечно, это вряд ли произойдет. – slartidan

0

Это зависит от реализации. Если вы проверите the documentation для ArrayList, который является фактическим классом, который вы используете, вы увидите это.

Броски: NullPointerException - если указанный набор является нулем

Так что ваши ArrayList не должны бросать IllegalArgumentException. Если вы использовали бы другую реализацию или обертку (см. unmodifiable list, примечание, что этот пример не генерирует такого исключения), это может вызвать такое исключение.

Так что получите регистрацию от пользователя и попытайтесь воспроизвести проблему.

Смежные вопросы