UnsupportedOperationException

Opis

UnsupportedOperationException jest wyjątkiem z grupy wyjątków niekontrolowanych (unchecked exceptions), co oznacza, że dziedziczy po klasie RuntimeException i nie mamy obowiązku jego obsługi. Wyjątek znajduje się w pakiecie java.lang, więc pełna ścieżka do niego wygląda następująco java.lang.ConcurrentModificationException.

Wyjątek jest rzucany w sytuacji, gdy jakaś operacja nie jest wspierana przez dany obiekt. Najczęściej metoda ta jest powiązana z kolekcjami niemodyfikowalnymi zwracanymi np. przez metody:

  • Arrays.asList()
  • List.of()
  • Set.of()
  • i metodami of() w innych kolekcjach, które zostały wprowadzone w Javie 9.

Kurs Java

Przykład 1 - tworzenie listy przy pomocy metody Arrays.asList().

UnsupportedExample1.java

import java.util.Arrays;
import java.util.List;

class UnsupportedExample1 {
    public static void main(String[] args) {
        List<Integer> numbers= Arrays.asList(5, 10, 15, 20, 25, 30);

        numbers.add(11);
        numbers.add(22);
        numbers.add(33);

        System.out.println(numbers);
    }
}

Tworzymy listę korzystając z wygodnej metody Arrays.asList(). Powstała w ten sposób lista zawiera obiekty, które przekazujemy w okrągłych nawiasach. W wyniku otrzymujemy obiekt klasy Arrays.ArrayList (nie jest to klasa java.util.ArrayList). Klasa Arrays.ArrayList nie ma zdefiniowanej ani metody add(), ani metody remove(), więc próba ich wywołania skończy się rzuceniem wyjątku UnsupportedOperationException.

Przykład 2 - metody factory w kolekcjach (Java 9+)

UnsupportedExample2.java

import java.util.Set;

class UnsupportedExample2 {
    public static void main(String[] args) {
        Set<Integer> numbers = Set.of(5, 10, 15, 20, 25, 30);

        numbers.add(11);
        numbers.add(22);
        numbers.add(33);

        System.out.println(numbers);
    }
}

Tym razem tworzymy zbiór korzystając ze statycznej metody Set.of() dostępnej od Javy 9. Jest to bardzo wygodny sposób na tworzenie kolekcji, której elementy są z góry znane. Problem pojawia się ponownie przy próbie wywołania metody add(), czyli dodania do zbioru jeszcze jakiejś wartości (podobnie będzie przy próbie usuwania). Metoda Set.of() zwraca niemodyfikowalny zbiór, czyli nie można do niego ani dodawać, ani usuwać istniejących elementów. Podobnie jak poprzednio w wyniku otrzymujemy wyjątek

unsupportedoperationexceptionTeoretycznie wywołania metody add() lub remove() moglibyśmy opakować w blok try catch, obsłużyć wyjątek i wyświetlić użytkownikowi komunikat, ale w praktyce nie ma to sensu, ponieważ taki wyjątek wystąpi zawsze. Jeżeli wiemy, że kolekcje, które tworzymy na początku, będą w przyszłości modyfikowane, to powinniśmy utworzyć obiekty kolekcji korzystając z odpowiednich konstruktorów.

Możemy zapisać:

class UnsupportedExample1 {
    public static void main(String[] args) {
//        List<Integer> numbers= Arrays.asList(5, 10, 15, 20, 25, 30);
        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(10);
        numbers.add(15);
        numbers.add(20);
        numbers.add(25);
        numbers.add(30);

        numbers.add(11);
        numbers.add(22);
        numbers.add(33);

        System.out.println(numbers);
    }
}

Albo krócej, łącząc korzyści metody Arrays.asList() z konstruktorem:

class UnsupportedExample1 {
    public static void main(String[] args) {
//        List<Integer> numbers= Arrays.asList(5, 10, 15, 20, 25, 30);
        List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 10, 15, 20, 25, 30));

        numbers.add(11);
        numbers.add(22);
        numbers.add(33);

        System.out.println(numbers);
    }
}

Metoda Arrays.asList() tworzy listę. Wszystkie obiekty z tej listy zostaną wstawione do listy, którą sami tworzymy wywołując konstruktor przez new ArrayList.

W identyczny sposób można postąpić w przypadku korzystania z metod of() dowolnych kolekcji.

import java.util.HashSet;
import java.util.Set;

class UnsupportedExample2 {
    public static void main(String[] args) {
//        Set<Integer> numbers = Set.of(5, 10, 15, 20, 25, 30);
        Set<Integer> numbers = new HashSet<>(Set.of(5, 10, 15, 20, 25, 30));

        numbers.add(11);
        numbers.add(22);
        numbers.add(33);

        System.out.println(numbers);
    }
}

Po uruchomieniu programu zobaczymy poprawny wynik.

unsuported_work

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzieliś spostrzeżeniami? Zapraszamy dyskusji na naszej grupe na Facebooku.