Sobes.tech
Middle

Jaké jsou možnosti v Generics?

sobes.tech AI

Odpověď od AI

Generika umožňují vytvářet parametrizované třídy, rozhraní a metody.

Hlavní funkce:

  • Opakované použití kódu: Vytváření univerzálních datových struktur a algoritmů, které fungují s jakýmkoli typem.
  • Bezpečnost typů při kompilaci: Chyby typu jsou detekovány ve fázi kompilace, nikoli při běhu. Odstraňuje potřebu manuálního přetypování a potenciální ClassCastException chyby.
  • Vylepšená čitelnost: Kód je srozumitelnější, protože jasně ukazuje, s jakými typy pracuje.

Příklady:

  • Třída kontejner List<T> může uchovávat prvky jakéhokoli typu T.
  • Metoda static <T> T getFirst(List<T> list) může vrátit první prvek libovolného seznamu.

Omezení generik:

  • Nelze vytvářet instance obecných typů: new T().
  • Nelze používat primitivní typy jako parametry typu (například List<int> - nesprávně, je třeba List<Integer>).
  • Nelze přímo vytvářet pole obecných typů (například T[] array = new T[10] - nesprávně, je třeba použít ArrayList nebo přetypování).
  • Nelze přímo používat statická pole obecných typů.
  • Informace o typech jsou při běhu odstraněny (Type Erasure), s výjimkou omezených wildcards.

Wildcards a omezené parametry typu:

  • <?>: Neznámý typ. Umožňuje číst prvky, ale ne zapisovat.
  • <? extends T>: Horní omezení. Umožňuje pracovat s typy, které jsou podtřídy T. Lze číst prvky typu T nebo jeho supertřídy, ale nelze zapisovat (kromě null).
  • <? super T>: Dolní omezení. Umožňuje pracovat s typy, které jsou nadtřídy T. Lze zapisovat prvky typu T nebo jeho podtřídy, ale při čtení lze získat pouze Object.

Příklad:

// Metoda, která může tisknout prvky z jakéhokoli seznamu obsahujícího podtřídy Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Chyba kompilace
}

// Metoda, která může přidat Integer do seznamu
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Chyba kompilace, vrací Object
}