Exemplu tutorial Java Generics – Metodă generică, clasă, interfață
Java Genrics este una dintre cele mai importante caracteristici introduse în Java 5.
Dacă ați lucrat la Java Collections și cu versiunea 5 sau mai recentă, sunt sigur că ați folosit-o.
Genericele în Java cu clase de colecție sunt foarte ușoare, dar oferă mult mai multe funcții decât simpla creare a tipul de colecție.
Vom încerca să aflăm caracteristicile genericelor din acest articol. Înțelegerea genericelor poate deveni confuză uneori dacă mergem cu cuvinte de jargon, așa că aș încerca să o păstrez simplu și ușor de înțeles.
Generics în Java
Generics a fost adăugat în Java 5 pentru a oferi verificarea tipului de compilare și eliminarea riscului de ClassCastException
care era obișnuit în timpul lucrului cu cursuri de colectare. Întregul cadru de colecție a fost rescris pentru a utiliza generice pentru siguranța tipului. Să vedem cum genericele ne ajută să folosim clasele de colectare în siguranță.
Codul de mai sus se compilează bine, dar aruncă ClassCastException în timpul rulării, deoarece încercăm să aruncăm obiectul în listă în șir, în timp ce unul dintre elemente este de tip întreg. După Java 5, folosim clase de colecție ca mai jos.
Observați că la momentul creării listei, am specificat că tipul de elemente din listă va fi Șir. Deci, dacă încercăm să adăugăm orice alt tip de obiect în listă, programul va arunca o eroare în timpul compilării. De asemenea, observați că în bucla for, nu avem nevoie de tipografiere a elementului din listă, prin urmare eliminăm ClassCastException la runtime.
Java Generic Class
Ne putem defini propriile clase cu tip generic. Un tip generic este o clasă sau o interfață care este parametrizată pe tipuri. Folosim paranteze unghiulare (< >) pentru a specifica parametrul tip.
Pentru a înțelege beneficiul, să spunem avem o clasă simplă ca:
Observați că, în timp ce utilizați această clasă, trebuie să folosim castingul de tip și poate produce ClassCastException în timpul rulării. Acum vom folosi clasa generică Java pentru a rescrie aceeași clasă așa cum se arată mai jos.
Observați utilizarea clasei GenericsType în metoda principală. Nu este nevoie să facem casting de tip și putem elimina ClassCastException în timpul rulării. Dacă nu furnizăm tipul în momentul creării, compilatorul va produce un avertisment că „GenericsType este un tip brut.
Referințe la tipul generic GenericsType < T > ar trebui parametrizat ”. Când nu furnizăm tipul, tipul devine Object
și, prin urmare, permite ambele șiruri și obiecte Integer. Dar ar trebui să încercăm întotdeauna să evităm acest lucru, deoarece va trebui să folosim castingul de tip în timp ce lucrăm pe tipul brut care poate produce erori de rulare.
@SuppressWarnings("rawtypes")
adnotare pentru a suprima avertismentul compilatorului, consultați tutorialul de adnotări java. De asemenea, observați că acceptă java autoboxing.
Interfața generică Java
Interfața comparabilă este un exemplu excelent de generice în interfețe și este scrisă ca:
În mod similar, putem crea interfețe generice în java. au mai mulți parametri de tip ca în interfața Map câștig putem oferi, de asemenea, valoare parametrizată unui tip parametrizat, de exemplu, new HashMap<String, List<String>>();
este valid.
Tip generic Java
Denumire tip generic Java convenția ne ajută să înțelegem codul cu ușurință și să avem o convenție de numire este una dintre cele mai bune practici ale limbajului de programare Java. Deci, genericul vine și cu propriile sale convenții de denumire. De obicei, numele parametrilor de tip sunt litere mari, majuscule, pentru a-l face ușor de distins de variabilele java. Cele mai utilizate nume de parametri de tip sunt:
- E – Element (utilizat pe scară largă de Java Collections Framework, de exemplu ArrayList, Set etc.)
- K – Key ( Folosit în hartă)
- N – Număr
- T – Tip
- V – Valoare (Folosit în hartă)
- S, U, V etc. – 2, 3, 4 tipuri
Metoda generică Java
Uneori nu vrem ca întreaga clasă să fie parametrizată, în acest caz, putem creați metoda generice java. Deoarece constructorul este un tip special de metodă, putem folosi tipul generic și în constructori.
Iată o clasă care prezintă un exemplu de metodă generică Java.
Observați metoda isEqual semnătura care arată sintaxa pentru a utiliza tipul de generice în metode. De asemenea, observați cum să utilizați aceste metode în programul nostru Java. Putem specifica tipul în timp ce apelăm aceste metode sau le putem invoca ca o metodă normală. Compilatorul Java este suficient de inteligent pentru a determina tipul de variabilă care trebuie utilizată, această facilitate se numește inferență de tip.
Parametrii tipului limită Java Generics
Să presupunem că dorim să restricționăm tipul de obiecte care pot fi utilizate în tipul parametrizat, de exemplu într-o metodă care compară două obiecte și dorim să asigurați-vă că obiectele acceptate sunt comparabile. Pentru a declara un parametru de tip delimitat, enumerați numele parametrului de tip, urmat de cuvântul cheie extends, urmat de limita superioară a acestuia, similar cu metoda de mai jos.
invocarea acestor metode este similară cu metoda nelimitată, cu excepția faptului că, dacă vom încerca să folosim orice clasă care nu este comparabilă, va arunca o eroare în timp de compilare.
Parametrii tipului delimitați pot fi utilizați cu metode, precum și cu clase și interfețe.
Java Generics acceptă, de asemenea, limite multiple, adică < T extinde A & B & C >. În acest caz, A poate fi o interfață sau o clasă. Dacă A este clasă, atunci B și C ar trebui să fie o interfață. Nu putem avea mai mult de o clasă în limite multiple.
Generici și moștenire Java
Știm că Moștenirea Java ne permite să atribuim o variabilă A unei alte variabile B dacă A este subclasa B. Așa că am putea crede că orice tip generic de A poate fi atribuit tipului generic de B, dar nu este cazul. Să vedem acest lucru cu un program simplu.
Nu avem voie să atribuim variabila MyClass < Șir > MyClass < Variabila obiect > deoarece nu sunt corelate, de fapt MyClass < T > părintele este Object.
Clasele și subtiparea generice Java
Putem subtipa o clasă sau o interfață generică prin extinderea sau implementarea acesteia. Relația dintre parametrii de tip ai unei clase sau interfețe și parametrii de tip ai alteia este determinată de clauzele extends and implements.
Relația de subtipare este păstrată atâta timp cât nu modificăm argumentul de tip, mai jos arată un exemplu de parametri de tip multiplu.
Subtipurile Listei < Șir > poate fi MyList < Șir, obiect >, MyList < String, Integer > și așa mai departe.
Java Generics Wildcards
Semnul de întrebare (?) Este wildcard-ul generic și reprezintă un tip necunoscut. Caracterul wildcard poate fi folosit ca tip de parametru, câmp sau variabilă locală și uneori ca tip de returnare. Nu putem folosi metacaractere în timp ce invocăm o metodă generică sau instanțiem o clasă generică. În secțiunile următoare, vom învăța despre metacaracterele delimitate superioare, metacaracterele delimitate inferior și capturarea cu metacaracter. restricție asupra tipului de variabilă într-o metodă. Să presupunem că vrem să scriem o metodă care va returna suma numerelor din listă, astfel încât implementarea noastră va fi ceva de genul acesta.
Acum problema cu implementarea de mai sus este că nu va funcționa cu Listă de numere întregi sau duble deoarece știm că List < Număr întreg > și List < Dublul > nu are legătură, atunci când este utilă o caracteră comodă delimitată. Folosim metacaractice generice cu cuvântul cheie extends și clasa sau interfața de limită superioară care ne va permite să trecem argumentul limitelor superioare sau a tipurilor de subclasă.
Implementarea de mai sus poate fi modificată ca și programul de mai jos.
Este similar cu scrierea codului nostru în termeni de interfață, în metoda de mai sus putem folosi toate metodele clasei de limită superioară Number. Rețineți că, cu lista delimitată în partea superioară, nu avem voie să adăugăm niciun obiect la listă, cu excepția lui nul. Dacă vom încerca să adăugăm un element în listă în cadrul metodei sumă, programul nu va compila.
9.2) Java Generics Unbounded Wildcard
Uneori avem o situație în care dorim ca metoda noastră generică să funcționeze cu toate tipurile, în acest caz, se poate folosi un wildcard nelimitat. Este la fel ca și utilizarea <? extends Object >.
Putem furniza Listă < Șir > sau List < Întreg > sau orice alt tip de argument din lista de obiecte la metoda printData. Similar listei cu limita superioară, nu avem voie să adăugăm nimic la listă.
9.3) Java Generics Joker cu delimitare inferioară
Să presupunem că dorim să adăugăm Numere întregi la o listă de numere întregi într-o metodă, putem păstra tipul argumentului ca Listă < Număr întreg >, dar va fi legat cu numere întregi, în timp ce List < Număr > și List < Obiectul > poate conține, de asemenea, numere întregi, astfel încât să putem realiza un wildcard cu limită inferioară. Folosim metacaractice generice (?) Cu super cuvânt cheie și clasă cu limită inferioară pentru a realiza acest lucru.
Putem trece limita inferioară sau orice tip supertip de limită inferioară ca argument, în acest caz, compilatorul java permite să adăugați mai mici tipuri de obiecte legate la listă.
Subtiparea utilizând Generics Wildcard
Java Generics Type Erasure
Generics in Java a fost adăugat pentru a oferi verificarea tipului la momentul compilării și nu are niciun folos în timpul rulării, astfel încât compilatorul Java folosește caracteristica de ștergere a tipului pentru a elimina toate codurile de verificare a tipului generice din codul de octeți și pentru a insera tipărirea de tip, dacă este necesar. Ștergerea tipurilor asigură faptul că nu sunt create clase noi pentru tipurile parametrizate; în consecință, genericele nu suportă costuri de execuție.
De exemplu, dacă avem o clasă generică ca mai jos;
Compilatorul Java înlocuiește parametrul de tip delimitat T cu prima interfață legată, comparabil , după cum urmează codul:
Întrebări frecvente despre generice
12.1) De ce folosim Generice în Java?
Genericele asigură o verificare puternică a tipului de timp de compilare și reduce riscul de ClassCastException și distribuirea explicită a obiectelor.
12.2) Ce este T în Generics?
Folosim < T > pentru a crea o clasă, o interfață și o metodă generice. T este înlocuit cu tipul real când îl folosim.
12.3) Cum funcționează Generics în Java?
Codul generic asigură siguranța tipului. Compilatorul folosește ștergerea tipului pentru a elimina toți parametrii de tip la momentul compilării pentru a reduce supraîncărcarea la runtime.
Generice în Java – Lecturi ulterioare
Asta este tot pentru generice în java, java genericele sunt un subiect cu adevărat vast și necesită mult timp pentru ao înțelege și a-l folosi eficient. Această postare aici este o încercare de a oferi detalii de bază despre generice și cum o putem folosi pentru a extinde programul nostru cu tip-siguranță.