Java Generics - vs.

1. Prehľad

V tomto rýchlom návode uvidíme podobnosti a rozdiely medzi a v prostredí Java Generics.

Keďže sa však jedná o pokročilú tému, je nevyhnutné získať základné pochopenie témy skôr, ako sa ponoríme do jadra veci.

2. Pozadie generík

V JDK 5 boli zavedené generiká, ktoré eliminujú chyby v čase kompilácie a posilňujú bezpečnosť typov. Táto mimoriadna bezpečnosť typu eliminuje prenášanie v niektorých prípadoch použitia a umožňuje programátorom písať všeobecné algoritmy, ktoré môžu viesť k čitateľnejšiemu kódu.

Napríklad pred JDK 5 by sme museli pracovať s prvkami zoznamu pomocou castingu. To zase vytvorilo určitú triedu runtime chýb:

Zoznam aList = nový ArrayList (); aList.add (nové celé číslo (1)); aList.add ("a_string"); for (int i = 0; i <aList.size (); i ++) {Integer x = (Integer) aList.get (i); }

Tento kód má teraz dva problémy, ktorým by sme sa chceli venovať:

  • Na extrahovanie hodnôt potrebujeme explicitné obsadenie zoznam - typ závisí od typu premennej vľavo - Celé číslo v tomto prípade
  • Pri pokuse o cast dostaneme runtime chybu pri druhej iteracii a_string do an Celé číslo

Rolu pre nás plnia generiká:

Zoznam iList = nový ArrayList (); iList.add (1); iList.add ("a_string"); // chyba času kompilácie pre (int i = 0; i <iList.size (); i ++) {int x = iList.get (i); } 

Kompilátor nám oznámi, že nie je možné pridať a_string do a Zoznam typu Celé číslo, čo je lepšie ako zisťovať za behu.

Navyše nie je potrebné žiadne výslovné odovzdávanie, pretože to už kompilátor vie iList drží Celé číslos. Navyše sme kvôli kúzlu unboxingu ani nepotrebovali Celé číslo typu, stačí jeho primitívna forma.

3. Zástupné znaky v generike

Otazník alebo zástupný znak sa v generike používa na predstavenie neznámeho typu. Môže mať tri formy:

  • Bez obmedzenia pre zástupné znaky: Zoznam predstavuje zoznam neznámeho typu
  • Horné ohraničené zástupné znaky: Zoznam predstavuje zoznam Číslo alebo jeho podtypy ako napr Celé číslo a Dvojitý
  • Zástupné znaky s dolnými hranicami: Zoznam predstavuje zoznam Celé číslo alebo jeho supertypy Číslo a Objekt

Teraz, od Objekt je inherentný supertyp všetkých typov v Jave, boli by sme v pokušení myslieť si, že môže predstavovať aj neznámy typ. Inými slovami, Zoznam a Zoznam môže slúžiť rovnakému účelu. Ale oni nie.

Zvážme tieto dve metódy:

public static void printListObject (List list) {for (Object element: list) {System.out.print (element + ""); }} public static void printListWildCard (List list) {for (Object element: list) {System.out.print (element + ""); }} 

Vzhľadom na zoznam Celé číslos, povedzme:

Zoznam li = Arrays.asList (1, 2, 3);

printListObject (li) sa nebude kompilovať a zobrazí sa nám táto chyba:

Metóda printListObject (List) nie je použiteľná pre argumenty (List)

Keďže printListWildCard (li) skompiluje a vypíše 1 2 3 do konzoly.

4. a - podobnosti

Vo vyššie uvedenom príklade, ak zmeníme podpis metódy pre printListWildCard do:

public static void printListWildCard (zoznam)

Fungovalo by to rovnako ako printListWildCard (zoznam) urobil. Je to spôsobené tým, že Objekt je supertyp všetkých objektov Java a v podstate sa všetko rozširuje Objekt. Takže, a Zoznam z Celé číslospracuje sa tiež.

V skratke, znamená to, že ? a ? rozširuje Object sú v tomto príklade synonymá.

Aj keď by to vo väčšine prípadov platilo, ale je tu tiež niekoľko rozdielov. Pozrime sa na ne v nasledujúcej časti.

5. a - rozdiel

Opätovateľné typy sú typy, ktorých typ sa v čase kompilácie nevymaže. Inými slovami, reprezentácia za behu nerefikovateľného typu bude mať menej informácií ako jej náprotivok v čase kompilácie, pretože niektoré z nich budú vymazané.

Všeobecne platí, že parametrizovateľné typy nie je možné znova meniť. To znamená Zoznam a Mapa nie sú oprávniteľné. Kompilátor vymaže ich typ a zaobchádza s nimi ako s Zoznam a Mapa resp.

Jedinou výnimkou z tohto pravidla sú neobmedzené zástupné typy. To znamená Zoznam a Mapa sú preukázateľné.

Na druhej strane, Zoznam nie je možné preukázať. Aj keď je to jemné, je to pozoruhodný rozdiel.

Typy, ktoré nemožno opätovne vymenovať, sa nedajú použiť v určitých situáciách, napríklad v inštancia operátor alebo ako prvky poľa.

Takže, ak napíšeme:

Zoznam someList = new ArrayList (); boolean instanceTest = someList instanceof List

Tento kód zostavuje a instanceTest je pravda.

Ale ak použijeme inštancia operátor zapnutý Zoznam:

Zoznam anotherList = new ArrayList (); boolean instanceTest = anotherList instanceof List;

potom sa riadok 2 nezkompiluje.

Podobne sa v nasledujúcom úryvku kompiluje riadok 1, ale riadok 2 nie:

List [] arrayOfList = nový zoznam [1]; Zoznam [] arrayOfAnotherList = nový Zoznam [1]

6. Záver

V tomto krátkom tutoriáli sme videli podobnosti a rozdiely v a .

Aj keď sú väčšinou podobné, existujú medzi nimi jemné rozdiely, pokiaľ ide o to, či sú alebo nie sú použiteľné.


$config[zx-auto] not found$config[zx-overlay] not found