Un tip generic este o clasă sau o interfață generică care este parametrizată pe tipuri. Următoarea clasă Box va fi modificată pentru a demonstra conceptul.
O clasă Box simplă
Începeți examinând o clasă Box non-generică care funcționează pe obiecte de orice tip. Trebuie doar să furnizeze două metode: set, care adaugă un obiect în casetă și get, care îl recuperează:
Deoarece metodele sale acceptă sau returnează un obiect, ești liber să treci în orice vrei , cu condiția să nu fie unul dintre tipurile primitive. Nu există nicio modalitate de a verifica, la compilare, modul în care este utilizată clasa. O parte a codului poate plasa un număr întreg în casetă și se așteaptă să scoată numerele întregi din acesta, în timp ce o altă parte a codului poate trece în mod eronat într-un șir, rezultând o eroare de execuție.
O versiune generică din clasa Box
O clasă generică este definită cu următorul format:
class name<T1, T2, ..., Tn> { /* ... */ }
Pentru a actualiza Clasa Box pentru a utiliza generice, creați o declarație de tip generic schimbând codul „public class Box” la „public class Box < T > „. Aceasta introduce variabila de tip, T, care poate fi utilizată oriunde în clasă.
Odată cu această modificare, clasa Box devine:
După cum puteți vedea, toate aparițiile Obiectului sunt înlocuită cu T. O variabilă de tip poate fi orice tip neprimitiv pe care îl specificați: orice tip de clasă, orice tip de interfață, orice tip de matrice sau chiar un alt tip de variabilă.
Aceeași tehnică poate fi aplicată pentru a crea interfețe generice.
Convenții de numire a parametrilor de tip
Prin convenție, numele parametrilor de tip sunt litere mari, majuscule. Acest lucru contrastează puternic cu convențiile de denumire a variabilelor despre care știți deja și cu un motiv întemeiat: Fără această convenție, ar fi dificil să se facă diferența dintre o variabilă de tip și o clasă obișnuită sau un nume de interfață.
Cele mai utilizate nume de parametri de tip sunt:
- E – Element (utilizat pe scară largă de Java Collections Framework)
- K – Key
- N – Număr
- T – Tip
- V – Valoare
- S, U, V etc. – 2, 3, 4 tipuri
Veți vedea aceste nume folosite în Java SE API și în restul acestei lecții.
Invocarea și instanțarea unui tip generic
Pentru a face referire la clasa generică a clasei Box din interiorul codului dvs., trebuie să efectuați o invocare de tip generic, care înlocuiește T cu o anumită valoare concretă, cum ar fi Întreg:
Box<Integer> integerBox;
Vă puteți gândi la o invocare de tip generic ca fiind similară cu o invocare obișnuită a metodei, dar în loc să transmiteți un argument la am etod, treceți un argument de tip – întreg în acest caz – la clasa Box.
La fel ca orice altă declarație de variabilă, acest cod nu creează de fapt un obiect Box nou. Pur și simplu declară că integerBox va conține o referință la o „Casetă de număr întreg”, care este modul în care se citește Caseta < Număr întreg >.
O invocație de tip generic este cunoscută în general ca tip parametrizat.
Pentru a instanția această clasă, utilizați noul cuvânt cheie, ca de obicei, dar plasați < Număr întreg > între numele clasei și paranteză:
Box<Integer> integerBox = new Box<Integer>();
Diamantul
În Java SE 7 și versiunile ulterioare, puteți înlocui argumentele de tip necesare pentru a invoca constructorul unei clase generice cu un set gol de argumente de tip (< >) atâta timp cât compilatorul poate determina sau deduce argumentele de tip din context. Această pereche de paranteze unghiulare, < >, se numește informal diamant. De exemplu, puteți crea o instanță a casetei < Întreg > cu următoarea declarație:
Box<Integer> integerBox = new Box<>();
Pentru mai multe informații despre notația diamantului și inferența de tip, consultați inferența tipului.
Parametri de tip multiplu
După cum sa menționat anterior, o clasă generică poate avea mai mulți parametri de tip.De exemplu, clasa generică OrderedPair, care implementează interfața generică Pair:
Următoarele instrucțiuni creează două instanțieri ale clasei OrderedPair:
Codul, nou OrderedPair < String, Integer >, instanțiază K ca un șir și V ca un întreg. Prin urmare, tipurile de parametri ai constructorului OrderedPair sunt, respectiv, String și Integer. Datorită autoboxing-ului, este valid să treci un String și un int către clasă.
După cum sa menționat în The Diamond, deoarece un Compilatorul Java poate deduce tipurile K și V din declarația OrderedPair < Șir, întreg >, aceste afirmații pot fi scurtate folosind notația diamant:
OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);OrderedPair<String, String> p2 = new OrderedPair<>("hello", "world");
Pentru a crea o interfață generică, urmați aceleași convenții ca și pentru crearea unei clase generice.
Tipuri parametrizate
OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));