Sobes.tech
Middle

Kokios galimybės yra Generics?

sobes.tech AI

Atsakymas iš AI

Gaminiai generikai leidžia kurti parametrizuotus klases, sąsajas ir metodus.

Pagrindinės galimybės:

  • Kodo pakartotinis naudojimas: Sukurti universalias duomenų struktūras ir algoritmus, kurie veikia su bet kokiais tipais.
  • Tipų saugumas kompiliacijos metu: Tipų klaidos nustatomos kompiliacijos metu, o ne vykdymo metu. Tai pašalina poreikį rankiniu būdu konvertuoti tipus ir susijusias galimas klaidas ClassCastException.
  • Skaitymo gerinimas: Kodas tampa aiškesnis, nes aiškiai nurodo, su kokiais tipais jis dirba.

Pavyzdžiai:

  • List<T> klasė gali saugoti bet kokio tipo T elementus.
  • static <T> T getFirst(List<T> list) metodas gali grąžinti pirmą elementą iš bet kokio tipo sąrašo.

Generics apribojimai:

  • Negalima kurti generinio tipo egzempliorių: new T().
  • Negalima naudoti primitivių tipų kaip tipo parametrų (pavyzdžiui, List<int> - neteisinga, reikia List<Integer>).
  • Negalima tiesiogiai kurti generinių tipų masyvų (pavyzdžiui, T[] array = new T[10] - neteisinga, naudokite ArrayList arba tipų konversiją).
  • Negalima naudoti statinių laukų tiesiogiai su generiniais tipais.
  • Informacija apie tipus ištrinama vykdymo metu (Type Erasure), išskyrus bounded wildcards.

Wildcards ir bounded Type Parameters:

  • <?>: Nežinomas tipas. Leidžia skaityti elementus, bet ne rašyti.
  • <? extends T>: Viršutinė riba. Leidžia dirbti su tipais, kurie yra T subtipai. Gali skaityti T arba jo supertipų elementus, bet negali rašyti (išskyrus null).
  • <? super T>: Apatinė riba. Leidžia dirbti su tipais, kurie yra T supertipai. Gali rašyti T arba jo subtipų elementus, bet gali skaityti tik Object tipus.

Pavyzdys:

// Metodas, kuris gali spausdinti elementus iš bet kurios sąrašo,
// kuris turi `Number` subtipus
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Kompiliacijos klaida
}

// Metodas, kuris gali pridėti `Integer` į sąrašą,
// kuris turi `Integer` arba jo supertipus
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Kompiliacijos klaida, grąžina `Object`
}