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í
ClassCastExceptionchyby. - 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 typuT. - 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řebaList<Integer>). - Nelze přímo vytvářet pole obecných typů (například
T[] array = new T[10]- nesprávně, je třeba použítArrayListnebo 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řídyT. Lze číst prvky typuTnebo jeho supertřídy, ale nelze zapisovat (kroměnull).<? super T>: Dolní omezení. Umožňuje pracovat s typy, které jsou nadtřídyT. Lze zapisovat prvky typuTnebo jeho podtřídy, ale při čtení lze získat pouzeObject.
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
}