Sobes.tech
Middle

Jakie możliwości oferują Generics w Java?

sobes.tech AI

Odpowiedź od AI

Generics w Java zwiększają bezpieczeństwo typów kodu, zapobiegając błędom czasu wykonania związanym z rzutowaniem typów. Główne możliwości:

  • Weryfikacja typów na etapie kompilacji: Kompilator sprawdza poprawność użycia typów określonych w Generics, co pozwala wykryć błędy przed uruchomieniem programu.

    // Bez Generics - możliwy ClassCastException
    List list = new ArrayList();
    list.add("łańcuch");
    list.add(123); // Dodanie Integer
    String s = (String) list.get(1); // Błąd w czasie wykonania
    
    // Z Generics - błąd kompilacji
    List<String> stringList = new ArrayList<>();
    stringList.add("łańcuch");
    // stringList.add(123); // Błąd kompilacji
    String str = stringList.get(0); // Bezpieczne pobranie
    
  • Usunięcie rzutowania typów (type casting): Generics eliminują konieczność jawnego rzutowania przy pobieraniu elementów z kolekcji lub korzystaniu z klas parametryzowanych.

    // Bez Generics
    List list = new ArrayList();
    list.add("Cześć");
    String s = (String) list.get(0); // Jawne rzutowanie
    
    // Z Generics
    List<String> stringList = new ArrayList<>();
    stringList.add("Cześć");
    String str = stringList.get(0); // Rzutowanie nie jest potrzebne
    
  • Implementacja kodu generycznego (Metody generyczne, Klasy generyczne, Interfejsy generyczne): Pozwalają tworzyć uniwersalne algorytmy i struktury danych, które działają z różnymi typami, nie duplikując kodu.

    // Metoda generyczna do drukowania tablicy
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
    
    // Klasa generyczna - para wartości
    class Pair<K, V> {
        private K key;
        private V value;
    
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey() { return key; }
        public V getValue() { return value; }
    }
    
  • Wsparcie Wildcards: Pozwalają na definiowanie elastycznych ograniczeń typów w parametryzowanych typach.

    • ? (Wildcard bez ograniczeń): Dowolny typ.
    • ? extends T (Wildcards z ograniczeniem górnym): Typ musi być T lub jego podtypem.
    • ? super T (Wildcards z ograniczeniem dolnym): Typ musi być T lub jego supertypem.
    // Metoda przyjmująca listę dowolnego typu
    public static void processList(List<?> list) {
        // ...
    }
    
    // Metoda przyjmująca listę liczb lub ich podtypów
    public static void processNumbers(List<? extends Number> list) {
        // ...
    }
    
    // Metoda przyjmująca listę łańcuchów lub ich supertypów
    public static void addStrings(List<? super String> list) {
        list.add("nowy łańcuch");
    }
    
  • Użycie w frameworku Collections: Wszystkie główne klasy kolekcji (List, Set, Map itd.) są parametryzowane, co czyni pracę z kolekcjami bezpieczniejszą i wygodniejszą.

Generics są kluczowym elementem nowoczesnego Java, zwiększającym niezawodność i czytelność kodu.