Sobes.tech
Middle

Jakie są możliwości w Generics?

sobes.tech AI

Odpowiedź od AI

Generics pozwalają na tworzenie klas, interfejsów i metod parametryzowanych.

Główne możliwości:

  • Ponowne użycie kodu: Tworzenie uniwersalnych struktur danych i algorytmów działających z dowolnym typem.
  • Bezpieczeństwo typów podczas kompilacji: Błędy typów są wykrywane na etapie kompilacji, a nie podczas wykonywania. Usuwa konieczność ręcznego rzutowania i potencjalne błędy ClassCastException.
  • Lepsza czytelność: Kod staje się bardziej zrozumiały, ponieważ wyraźnie wskazuje, z jakimi typami pracuje.

Przykłady:

  • Klasa kontener List<T> może przechowywać elementy dowolnego typu T.
  • Metoda static <T> T getFirst(List<T> list) może zwracać pierwszy element dowolnej listy.

Ograniczenia Generics:

  • Nie można tworzyć instancji typu generycznego: new T().
  • Nie można używać typów prymitywnych jako parametrów typu (np. List<int> - niepoprawne, należy użyć List<Integer>).
  • Nie można tworzyć tablic typu generycznego bezpośrednio (np. T[] array = new T[10] - niepoprawne, należy użyć ArrayList lub rzutowania).
  • Nie można używać statycznych pól typu generycznego bezpośrednio.
  • Informacje o typach są wymazywane na etapie wykonywania (Type Erasure), z wyjątkiem ograniczonych wildcardów.

Wildcards i ograniczone parametry typu:

  • <?>: Nieznany typ. Pozwala na odczyt elementów, ale nie na zapis.
  • <? extends T>: Ograniczenie górne. Pozwala na pracę z typami będącymi podtypami T. Można odczytywać elementy typu T lub jego supertypów, ale nie można ich zapisywać (z wyjątkiem null).
  • <? super T>: Ograniczenie dolne. Pozwala na pracę z typami będącymi supertypami T. Można zapisywać elementy typu T lub jego podtypów, ale odczytując można tylko otrzymać Object.

Przykład:

// Metoda, która może drukować elementy dowolnej listy zawierającej podtypy Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Błąd kompilacji
}

// Metoda, która może dodawać Integer do listy,
// zawierającej Integer lub jej supertypy
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Błąd kompilacji, zwraca Object
}