Sobes.tech
Middle

Czym jest wildcard w Java?

sobes.tech AI

Odpowiedź od AI

Symbol wieloznaczny (?) w Javie jest używany w generykach do reprezentowania nieznanego typu. Pozwala na pracę z kolekcjami zawierającymi elementy różnych kompatybilnych typów, bez ścisłego powiązania z konkretnym typem.

Główne scenariusze użycia:

  1. ? (Wildcards z ograniczeniem górnym): Oznacza dowolny typ będący podtypem lub implementujący wskazaną klasę/interfejs. Używany do odczytu danych z kolekcji. Przykład: List<? extends Number> może zawierać List<Integer>, List<Double>, .getList<Long>.

    // Odczyt z kolekcji z ograniczeniem górnym
    public void processNumbers(List<? extends Number> numbers) {
        for (Number n : numbers) {
            System.out.println(n);
        }
        // numbers.add(new Integer(10)); // Błąd kompilacji - nie można dodawać elementów
    }
    
  2. ? (Wildcards z ograniczeniem dolnym): Oznacza dowolny typ będący supertypem wskazanej klasy/interfejsu lub tą klasą/interfejsem samym. Używany do zapisu danych do kolekcji (zasada PECS: Producer Extends, Consumer Super). Przykład: List<? super Integer> może zawierać List<Integer>, List<Number>, List<Object>.

    // Zapis do kolekcji z ograniczeniem dolnym
    public void addIntegers(List<? super Integer> list) {
        list.add(1);
        list.add(new Integer(2));
        // Object o = list.get(0); // Zwraca Object, ponieważ dokładny typ jest nieznany
    }
    
  3. ? (Wildcards bez ograniczenia): Oznacza dowolny typ. Równoważny z ? extends Object. Używany, gdy nie jest istotny faktyczny typ elementów kolekcji, np. do sprawdzania rozmiaru lub czyszczenia.

    // Praca z kolekcją dowolnego typu
    public void printList(List<?> list) {
        for (Object obj : list) {
            System.out.println(obj);
        }
        // list.add("hello"); // Błąd kompilacji - nie można dodawać elementów (z wyjątkiem null)
    }
    

Wildcards zwiększają elastyczność kodu, pozwalając metodom pracować z szerszym zakresem typów kolekcji, zachowując bezpieczeństwo typów. Dzięki nim można unikać duplikacji kodu dla metod wykonujących podobne operacje na różnych, ale kompatybilnych typach kolekcji.