Generiká 1 (Pokročilá JAVA epizóda 2)

174

Už názov tejto témy nám môže naznačiť, že budeme niečo generovať – niečo vytvárať. V tomto prípade budeme generovať dátové typy – generiká.

Predstav si, že napíšeš metódu, kde namiesto zadefinovania, teda určenia dátových typov (String, Object, Dog, Person …) – v návratovej hodnote, či v argumentoch metódy, by si napísal len generikum a až pri použití danej metódy by si zašpecifikoval s akými typmi tried ideme pracovať.

Generiká teda podporujú abstrakciu nad dátovými typmi. Ak máš metódu, ktorej argumenty alebo návratové hodnoty sú pevne dané a tieto pevne dané typy zmeníš za generiká, tak môžeš namiesto týchto pevne daných typov použiť akýkoľvek typ.

Tu sa otvára priestor na písanie viacúčelových metód, ktoré dokážu pracovať s rôznymi vstupnými typmi údajov.

Generiká nemožno aplikovať nad primitívnymi dátovými typmi, teda ich možno použiť len nad referenčnými.

Je nutné si to ukázať na príklade.Možno ti napadlo, že by si ako návratové hodnoty, alebo parametre metód mohol napísať ako Object. To by ti predsa dovoľovalo zadať do metódy hocijaký typ tried, lebo všetky dedia nakoniec od Object. Samozrejme toto by sa dalo, ale pri použití toho objektu by si musel robiť cast, teda pretypovanie na daný objekt. Použitím generík toto odpadáva.

Vytvorme si akoby box pre dátové typy. Vieme, že premennej typu Object vieme priradiť hocijaký iný objekt.

public class Box {
    private Object object;

    public void addObject(Object object) {
        this.object = object;
    }

    public Object getObject() {
        return object;
    }
}

Ak tento box použijem na prácu s rôznymi typmi, tak sa prejaví chyba až za behu programu.

public static void main(String[] args) {
    Box integerBox = new Box();
    integerBox.addObject("2");

    Integer integer = (Integer) integerBox.getObject(); //java.lang.ClassCastException
    System.out.println(integer);

}

Teda veľký pozor na výnimku java.lang.ClassCastException.

Ak ale metódy prepíšeme pomocou generík, tak sa nám chyba prejaví hneď pri písaní programu.

Zopakujeme si: výhodou pri písaní generík je, že sa vieme vyhnúť class castom. V našom prvom Boxe, sme museli pri vyťahovaní z premennej typu Object zadefinovať, aký object, teda aký typ objektu tam je. V našom prípade sme očakávali Integer.

Pozrime sa na príklad s genericky napísaným boxom.

public class GenericBox<P> {
    private P object;

    public void addObject(P object) {
        this.object = object;
    }

    public P getObject() {
        return object;
    }

    public static void main(String[] args) {
        GenericBox<String> stringGenericBox = new GenericBox<>();
        stringGenericBox.addObject("sfsdfs");

        String s = stringGenericBox.getObject();

        GenericBox<Integer> integerGenericBox = new GenericBox<>();
        integerGenericBox.addObject(454);
    }
}

Teraz keď vytváraš generic box, tak musíš zadefinovať typ.

GenericBox<String> stringGenericBox

Postup

Pri prerábaní našej triedy Box na GenericBox sme pri zadefinovaní názvu triedy predstavili medzi zobáčiky typový parameter <P>. Namiesto P sme mohli napísať aj iné písmenká. Typových parametrov vieme predstaviť viacero, oddelíme ich čiarkou.

class name<T1, T2, ..., Tn> { /* ... */ }

Takýmto predstavením alebo uvedením typových parametrov sme povedali, že takéto rôzne typy môžu byť použité hocikde vo vnútry našej triedy.

Konvencia

Pri písaní generík, pri uvádzaní typových parametrov je zaužívané používať veľké písmená anglickej abecedy.

Toto sú najviac používané konvencie:

  • E – Element (používané v Java Collections Framework)
  • K – Key
  • N – Number
  • T – Type
  • V – Value

Postup pokračovanie

Pri použití danej generickej triedy musíme uviesť presne aký typ má byť dosadený namiesto nášho typového parametru P.

GenericBox<Integer> integerBox;

Dobrý článok? Chceš dostávať ďalšie?

Už viac ako 6 200 ITečkárov dostáva správy e-mailom. Nemusíš sa báť, nie každé ráno. Len občasne.

Súhlasím so spracovaním mojich osobných údajov. ( Viac informácií. )

Tvoj email neposkytneme 3tím stranám. Posielame naňho len informácie z robime.it. Kedykoľvek sa môžeš odhlásiť.