2015-07-22 35 views
8

Mam kodKiedy obiekt List.addAll() rzuca wyjątek 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) { 
    ... 
} 

i zastanawiam się jak to może zdarzyć IllegalStateException zostać wyrzucony. Najwyraźniej zdarzyło się to użytkownikowi mojej aplikacji, ale nie jestem w stanie wyśledzić, co było nie tak.

Dokumentacja Collection.addAll() mówi:

IllegalArgumentException - jeśli nie wszystkie elementy mogą być dodawane w tym czasie ze względu na ograniczenia wstawiania

ale jakie są ograniczenia wstawiania?

Zgaduję, że to zależy od dokładnego typu kolekcji. Używam ArrayList, więc sprawdźmy dokumenty dla addAll() z List interfejsu:

IllegalArgumentException - jeśli niektóre właściwość elementu określonej kolekcji uniemożliwia dodaje do tej listy

Cóż, właściwość elementu może uniemożliwić dodanie elementu do listy? Moje obie kolekcje są tego samego typu, powinienem móc dodać wartości null.

Czy ktoś może mi to wyjaśnić?

+0

Po prostu kręcę tu w ciemności, ale czy może nie być połączony ze współbieżnością? – Mackiavelli

+0

Nie jest do końca jasne, której wersji Java używasz, ale kod źródłowy dla Java SE 6 nigdy nie zgłasza tego wyjątku z 'addAll()' z wyjątkiem pośrednio podczas uzyskiwania dostępu do 'Collection'. Czy widziałeś ślad stosu i czy jesteś pewien, gdzie wyjątek został zgłoszony? – Persixty

+6

Dodaj ślad stosu wyjątku do swojego pytania. – VGR

Odpowiedz

1

W zależności od ilości informacji uzyskanych od użytkownika może to nie być możliwe. Ale zgaduję i usuwam moją odpowiedź, jeśli pojawią się kolejne dowody, które ją naruszają. :)

Zakładając, że napisałeś cały kod, zgadzam się, że addAll() nie może rzucić IllegalStateException (a cała dyskusja na temat IllegalArgumentException jest nieistotna).

Domyślam się, że błąd nie pochodzi z połączenia addAll(), ale z innego wywołania w kodzie (nie pokazano), który próbuje manipulować jedną z tych kolekcji. To jest możliwe, aby uzyskać możliwe, aby uzyskać , próbując, na przykład, iterować listę (używając iteratora uzyskanego z .iterator()) i usunąć element, a następnie spróbować usunąć inny element bez wywoływania Iterator.next(). Podobnie, Iterator.set() może wyrzucić jeden w iteratorze uzyskanym z ArrayList. Sądzę więc, że gdzieś w trakcie manipulowania listą dzieje się jedna z tych rzeczy.

Alternatywnie istnieje wiele sposobów, w jakie można implementować implementacje kolekcji . Więc jeśli nie jesteśmy pewni, czy to dotyczyło ArrayList, to mamy niewiele do zrobienia.

0

Nie jestem świadomy żadnych implementacji (w bibliotece lub bibliotece), które powodują wyjątek IllegalArgumentException.

Ale można łatwo stworzyć własną implementację, która rzuca taki wyjątek. Interfejs Collection uświadamia użytkownikom, że implementator może użyć IllegalArgumentException - nie mówi się, że używają go użytkownicy.

Przykład:

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(); 
    } 

} 

Wskutek polecam tego podejścia:

  • sprawdzić swój kod, który dodajesz semantycznie uzasadnione elementy do swojej kolekcji. Nie dodawaj obiektów klasy Person do listy o nazwie postalCodes
  • obsłużyć dowolnego wyjątku dotyczącego środowiska wykonawczego w w odpowiedni sposób. Na przykład transakcji wycofania, czy rejestrowanie, informują użytkownika i/lub zespół wsparcia
  • rozważenia do poinformować rozmówców swojej metodzie (poprzez JavaDoc), że metoda może nie
1

Twój kod może nie rzucać IllegalArgumentException ponieważ ArrayList#addAll nie może wygenerować takiego wyjątku.

Aby uzyskać ten wyjątek, należy użyć kolekcji klasy implementującej, w której taki wyjątek może zostać zgłoszony. Możesz łatwo tworzyć własne przez rozszerzenie ArrayList i nadpisywanie zaangażowanych metod.

+1

Przyszłe wdrożenie 'ArrayList # addAll' ** mogłoby ** rzucić' IllegalArgumentException' (tj. Następną wersję jre). Ale oczywiście jest to mało prawdopodobne. – slartidan

0

To zależy od wdrożenia. Jeśli sprawdzisz the documentation dla ArrayList, która jest rzeczywistą klasą używaną, zobaczysz to.

Zgłasza: NullPointerException - jeśli określony zbiór jest null

więc ArrayList nie powinny rzucać IllegalArgumentException. Jeśli użyjesz innej implementacji lub opakowania (zobacz unmodifiable list, notatka, że ten przykład nie wyrzuci takiego wyjątku), może on wygenerować taki wyjątek.

Pobierz rejestrację od użytkownika i spróbuj odtworzyć problem.