Ce este Generics în Java?

Generics in Java a fost introdus în 2004 ca o caracteristică nouă a limbajului de programare Java și a făcut parte din versiunea JDK 5. Este cel mai utilizat pe scară largă împreună cu cadrul colecțiilor Java. În prezent, este una dintre cele mai proeminente și căutate caracteristici ale limbajului de programare Java.

Java generică a fost găsită de patru persoane, respectiv Gilad Bracha, Martin Odersky, David Stoutamire și Philip Wadler în 1998. A fost o extensie a limbajului Java care a acceptat tipurile generice. Acesta a fost menit să atingă două obiective principale care sunt:

  1. Tipul de siguranță
  2. Reutilizabilitatea codului

Definiția genericilor în Java

Generica poate fi definită ca o modalitate de a realiza reutilizarea codului, prin definirea claselor generice, a interfețelor, a constructorilor și a metodelor care pot fi utilizate cu diferite tipuri de date și, de asemenea, pentru a obține siguranța tipului prin declararea tipului de date utilizat în implementare înainte, eliminând astfel șansele unei erori de executare.

Cum sunt implementate generice în Java?

Genericele sunt implementate cu paranteze unghiulare „”. Parantezele conțin parametrul de tip „T” din interiorul acestora. Exemplu, . Parametrul tip „T” este un titular de locație care indică faptul că i se va atribui un tip de date în timpul rulării. De exemplu, o clasă generică va fi definită ca:

public class MyGenericClass (…)

Următorii sunt parametrii de tip standard:

  • T: Tip
  • E: Element
  • N: număr
  • K: cheie
  • V: valoare

S, U, V și așa mai departe sunt utilizate pentru a defini al doilea, al treilea și al patrulea parametru, în cazul în care se utilizează multi-parametri.

Înțelegerea genericilor în Java

Până acum vă veți putea întreba care este siguranța tipului și cum funcționează? Sau cum diferă clasele generice, interfețele, constructorii și metodele de clasele și metodele noastre obișnuite care le fac reutilizabile? Să aflăm.

Java fiind un limbaj scris tipic necesită să declarați „tipul” care este tipul de date al valorii deținute de variabilă înainte de a o utiliza.

Exemplu: String myString =”eduCBA”;

Aici „String” este tipul de date, „myString” este variabila care va deține o valoare al cărei tip este String.

Acum, dacă încercați să treceți o valoare booleană în locul unei șiruri, de exemplu:

String myBooleanStr = true;

Veți primi imediat o eroare de compilare în timp ce precizează „Tip nepotrivire: nu se poate converti de la booleană la String”.

Cum realizăm reutilizabilitatea codurilor cu genericii?

Acum, să definim o metodă obișnuită:

public static void welcome(String name)(
System.out.println("welcome to " + name);
)

Această metodă poate fi invocată numai prin trecerea unui parametru șir. De exemplu:

welcome(“eduCBA”);

Produsul său va fi „binevenit pentru eduCBA”.

Cu toate acestea, nu puteți invoca această metodă ocolind alte tipuri de date, cum ar fi numere întregi sau booleane. Dacă încercați să faceți acest lucru, vi se va solicita o eroare de compilare în timp ce precizează „Metoda binevenită (String) în tipul Runner nu se aplică pentru argumente (boolean)”. În sensul că nu puteți trece niciun alt tip de date la o metodă care acceptă doar un șir ca parametru.

Acest lucru înseamnă, de asemenea, dacă doriți să invocați o metodă similară pentru un tip de date diferit, va trebui să scrieți o metodă nouă care să accepte tipul de date necesar ca parametru. Această caracteristică a rescrierii metodelor cu parametrii diferitelor tipuri de date este cunoscută și subîncărcarea metodei. Dezavantajul major al acestui lucru este că crește dimensiunea codului dvs.

Cu toate acestea, am putea folosi, de asemenea, Generics pentru a rescrie metoda de mai sus și pentru a o folosi pentru orice tip de date dorim.

Definirea unei metode generice:

public static void welcome(T t)(
System.out.println("it is " + t);
)

Notă : Aici „t” este un obiect de tipul T. I se va atribui tipul de date care este utilizat pentru a invoca metoda.

Acum puteți reutiliza această metodă invocând-o pentru un șir când este necesar sau un boolean sau un număr întreg sau orice alt tip de date.

welcome("educate");
Integer Myint = 1;
welcome(Myint)
welcome(true);

Declarațiile de mai sus vor furniza rezultatele de mai jos:

Este Educa
Este 1
Asta e adevarat

Prin urmare, folosind aici generice, suntem capabili să reutilizăm metoda noastră pentru diferite tipuri de date.

Cum realizăm siguranța tipului folosind Generics?

Una dintre diferențele majore dintre Arrays și Colecție este aceea că Arrays poate stoca doar date omogene, în timp ce Colecțiile pot stoca date eterogene. Adică Colecțiile pot stoca orice tip / obiect de date definite de utilizator.

NOTĂ: Colecțiile pot conține doar obiecte (tip de date definite de utilizator) și nu un tip de date primitiv. Pentru a lucra cu date primitive, colecțiile de tip folosesc clase de înveliș.

Acum, să luăm în considerare o ArrayList.

ArrayList myList = new ArrayList();

Să adăugăm date de tip String, Integer și Double la obiectul ArrayList.

myList.add("eduCBA");
myList.add(1);
myList.add(5.2);

La imprimarea obiectului ArrayList putem vedea că acesta conține următoarele valori: (eduCBA, 1, 5.2).

Acum, dacă doriți să regăsiți aceste valori în variabile, atunci va trebui să le tastați.

String someStr = (String)myList.get(0);
Integer someInt = (Integer)myList.get(1);
Double someFlt = (Double)myList.get(2);

În cazul în care nu faceți tipcast, vi se va solicita o eroare de compilare în timp ce menționează „nepotrivire tip: nu se poate converti de la obiect la șir”.

Din aceasta, puteți trage concluzia că, în timp ce preluați obiectele din ArrayList, trebuie să îl tastați tipurilor respective. Întrebarea care apare aici este cum veți ști ce tip de date să îi transmiteți? În timp real, ArrayList-ul dvs. va conține mii de înregistrări și le va transmite tipografic în diferite tipuri de date pentru fiecare obiect individual nu va fi o opțiune. S-ar putea să terminați prin a-l tipifica la un tip de date greșit. Ce se întâmplă atunci?

De data aceasta nu veți primi o eroare de compilare, dar veți arunca o eroare de rulare în care se spune „Excepție în thread-ul„ principal ”java.lang.ClassCastException: java.lang.Integer nu poate fi trimis la java.lang.String la com.serviceClasess.Runner Principale (Runner.java:43)“.

Întrucât nu putem garanta tipul de date prezente într-o colecție (în acest caz ArrayList), ele sunt considerate nesigure de utilizat în ceea ce privește tipul. Aici intră în joc generice pentru a asigura siguranța tipului.

Folosind ArrayList cu Generics:

ArrayList myList = new ArrayList();

Observați că în interiorul parantezelor unghiulare „”, tipul String este specificat, ceea ce înseamnă că această implementare particulară a ArrayList poate deține doar date de tip String. Dacă încercați să adăugați orice alt tip de date, acesta va arunca pur și simplu o eroare de timp de compilare. Aici v-ați protejat tipul ArrayList eliminând șansa de a adăuga un tip de date diferit de „String”.

Acum, după ce ați specificat tipul de date care este permis să fie adăugat la colecția dvs. cu ajutorul unor articole generice, nu mai trebuie să îl introduceți în timp ce recuperați datele. Adică puteți prelua datele dvs. prin scrierea:

String someStr = myList.get(0);

Cum face Generics în Java să funcționeze atât de ușor?

Vă ajută să faceți ca colecțiile dvs. să fie de siguranță, asigurându-vă astfel că codul dvs. nu reușește ulterior, din cauza unei excepții de timp de rulare. De asemenea, salvează codificatorul de la nevoia de a tasta fiecare obiect din colecție, făcând dezvoltarea codului mai rapidă și mai ușoară. Folosind clase și metode generice, se poate reutiliza codul conform tipurilor de date necesare în timpul implementării.

Ce mai poți face cu Generics în Java?

Până acum am văzut cum putem obține siguranța tipului și reutilizarea codului cu ajutorul generice. Acum să ne uităm la celelalte caracteristici pe care le oferă genericii. Sunt:

  1. Tipuri delimitate și delimitate multiple
  2. Tastați wildcards

Tipul delimitat : În cazul unui tip delimitat, tipul de date al unui parametru este legat de un anumit interval. Acest lucru se realizează cu ajutorul cuvântului cheie „extinde”.

De exemplu, să luăm în considerare o clasă generică cu un parametru de tip delimitat care extinde interfața Runnable:

class myGenericClass()

Acum, în timp ce-și creează obiectul într-o altă clasă:

myGenericClass myGen = new myGenericClass();

Declarația de mai sus se va executa perfect fără nicio eroare. Aceasta este, în cazul tipului delimitat, puteți trece același tip de clasă sau tipul său de clasă copil. De asemenea, puteți lega tipul parametrului de o interfață și trece implementările sale atunci când o invocați, ca în cazul exemplului nostru de mai sus.

Ce se întâmplă dacă încercați să utilizați orice alt tip de parametru?

myGenericClass myGen = new myGenericClass();

În cazul de mai sus, veți primi o eroare de compilare în timp ce precizează „Neconcordanță legată: tipul Integer nu este un înlocuitor valabil pentru tipcast-ul tipului MyGenericClass”.

Mai multe tipuri delimitate: În cazul mai multor tipuri delimitate, putem lega tipul de date ale parametrilor la mai mult de un tip. De exemplu,

Class myGeneric()

În acest caz, puteți trece orice tip care extinde clasa de număr și implementează interfața Runnable. Cu toate acestea, atunci când se utilizează mai multe tipuri delimitate, trebuie menționate câteva lucruri:

  1. Nu putem extinde mai mult de o clasă simultan.
  2. Putem extinde orice număr de interfețe la un moment care nu există o limită pentru interfețe.
  3. Numele clasei ar trebui să fie întotdeauna întâi urmat de numele interfeței, dacă nu, va duce la o eroare de compilare.

Carduri de caractere tip: sunt reprezentate prin „?” - simbolul semnului de întrebare. Utilizează două cuvinte cheie principale:

se extinde (pentru a defini limita superioară) și super (pentru a defini limitele inferioare).

De exemplu,

ArrayList al

Acest obiect ArrayList „al” va conține orice date de tip T și toate subclasele sale.

ArrayList al

Acest obiect ArrayList „al” va conține orice date de tip T și toate superclasele sale.

Avantajele genericilor în Java

1. Flexibilitate : Generics oferă codului nostru flexibilitatea de a găzdui diferite tipuri de date cu ajutorul unor clase și metode generice.

2. Întreținerea și reutilizarea codului: Datorită claselor și metodelor generice nu este necesar să re-scrieți codul, în cazul unei modificări a cerințelor într-o etapă ulterioară, făcând codul mai ușor de întreținut și reutilizat.

3. Securitate de tip: Oferă siguranță de tip cadrului de colectare, definind tipul de date pe care colecția îl poate păstra în prealabil și eliminând toate șansele de eșec la timpul de rulare din cauza ClassCastException.

4. Eliminarea necesității de a dactilografiat: Deoarece tipurile de date deținute de colecții sunt deja determinate, nu este nevoie să o tastați la momentul regăsirii. Aceasta reduce lungimea codului și, de asemenea, reduce efortul unui coder.

Generică în abilități Java

Pentru a lucra cu Generics, ar trebui să fii bine versat cu elementele de bază ale Java. Ar trebui să înțelegeți cum funcționează verificarea tipului și tipul turnării. Cunoașterea temeinică a altor concepte, cum ar fi supraîncărcarea metodei, relația dintre clase de părinți și copii, interfețe și implementări ale acestora sunt necesare. De asemenea, este esențial să înțelegem diferența dintre tipurile de date primitive (tip de date definite de sistem) și obiecte (tipul de date definit de utilizator) atunci când este vorba de colaborarea cu cadrul de colectare.

De ce ar trebui să folosim Generics în Java?

Utilizarea generice face ca codul nostru să fie mai durabil, deoarece reduce nevoia de a rescrie codul specific tipului de date de fiecare dată când există o modificare a cerinței. Utilizând tipuri generice delimitate, puteți restricționa tipul de date și, în același timp, oferi flexibilitate codului dvs. prin definirea gamei sale. Codul dvs. este mai puțin probabil să eșueze într-un moment ulterior, deoarece asigură siguranța tipului, ceea ce face ca codul dvs. să fie mai puțin predispus la erori.

Domeniul de aplicare pentru Generics în Java

Domeniul generic este limitat la compilarea timpului. Aceasta înseamnă că conceptul generice este aplicabil numai la timpul de compilare, dar nu și la timpul de rulare. De exemplu,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Aici toate cele patru afirmații de mai sus sunt una și aceeași. Acestea vor permite adăugarea oricărui tip de date la obiectul listei.

Concluzie

Generics facilitează codificarea pentru un coder. Acesta diminuează șansele de a întâlni ClassCastException în timpul rulării, oferind verificări puternice de tip. Elimină complet necesitatea turnării de tip, ceea ce înseamnă că este necesar să fie scris mai puțin cod. Ne oferă fezabilitatea de a dezvolta algoritmi generici care sunt independenți de tipul de date cu care lucrează.

Articole recomandate

Acesta a fost un ghid pentru Ce este Generics în Java ?. Aici am discutat despre Abilitățile, domeniul de aplicare, lucrul, Înțelegerea și avantajul genericilor în Java. Puteți parcurge și alte articole sugerate pentru a afla mai multe -

  1. Ce este Common Gateway Interface
  2. Cum se instalează Java 8
  3. ce este sapunUI
  4. Ce este JavaScript?
  5. Booleane Java