Tutorial di esempio di Java Generics – Metodo generico, classe, interfaccia
Java Genrics è una delle funzionalità più importanti introdotte in Java 5.
Se hai lavorato su Java Collections e con la versione 5 o successiva, sono sicuro che l’hai usata.
Generics in Java con classi di raccolta è molto semplice ma fornisce molte più funzionalità rispetto alla semplice creazione del tipo di raccolta.
In questo articolo proveremo a imparare le caratteristiche dei generici. Capire i generici a volte può creare confusione se usiamo parole gergali, quindi proverei a mantenerlo semplice e facile da capire.
Generics in Java
Generics è stato aggiunto in Java 5 per fornire il controllo del tipo in fase di compilazione e rimuovere il rischio di ClassCastException
che era comune durante il lavoro con classi di raccolta. L’intero framework della raccolta è stato riscritto per utilizzare i generici per l’indipendenza dai tipi. Vediamo come i generici ci aiutano a utilizzare le classi di raccolta in modo sicuro.
Il codice sopra viene compilato correttamente ma genera ClassCastException in fase di esecuzione perché stiamo cercando di eseguire il cast di Object nell’elenco su String mentre uno degli elementi è di tipo Integer. Dopo Java 5, utilizziamo le classi di raccolta come di seguito.
Si noti che al momento della creazione dell’elenco, abbiamo specificato che il tipo di elementi nell’elenco sarà String. Quindi, se proviamo ad aggiungere qualsiasi altro tipo di oggetto nell’elenco, il programma genererà un errore in fase di compilazione. Si noti inoltre che nel ciclo for, non è necessario il typecasting dell’elemento nell’elenco, quindi rimuovere ClassCastException in fase di esecuzione.
Classe generica Java
Possiamo definire le nostre classi con tipo generici. Un tipo generico è una classe o un’interfaccia parametrizzata sui tipi. Usiamo le parentesi angolari (< >) per specificare il parametro del tipo.
Per comprendere il vantaggio, diciamo abbiamo una classe semplice come:
Notare che mentre si usa questa classe, dobbiamo usare il casting del tipo e può produrre ClassCastException in fase di esecuzione. Ora useremo la classe generica java per riscrivere la stessa classe mostrata di seguito.
Notare l’uso della classe GenericsType nel metodo principale. Non è necessario eseguire il casting del tipo e possiamo rimuovere ClassCastException in fase di esecuzione. Se non forniamo il tipo al momento della creazione, il compilatore produrrà un avviso che indica che “GenericsType è un tipo grezzo.
Riferimenti al tipo generico GenericsType < T > dovrebbe essere parametrizzato “. Quando non forniamo il tipo, il tipo diventa Object
e quindi consente sia String e oggetti Integer. Tuttavia, dovremmo sempre cercare di evitarlo perché dovremo utilizzare il casting del tipo mentre lavoriamo su un tipo non elaborato che può produrre errori di runtime.
@SuppressWarnings("rawtypes")
annotazione per sopprimere l’avviso del compilatore, controlla il tutorial sulle annotazioni java. Notare anche che supporta java autoboxing.
Interfaccia generica Java
L’interfaccia comparabile è un ottimo esempio di Generics nelle interfacce ed è scritta come:
Allo stesso modo, possiamo creare interfacce generiche in java. Possiamo anche avere più parametri di tipo come nell’interfaccia Map guadagno possiamo fornire un valore parametrizzato anche a un tipo parametrizzato, ad esempio new HashMap<String, List<String>>();
è valido.
Tipo generico Java
Denominazione tipo generico Java la convenzione ci aiuta a comprendere facilmente il codice e avere una convenzione di denominazione è una delle migliori pratiche del linguaggio di programmazione Java. Quindi i generici vengono forniti anche con le proprie convenzioni di denominazione. Di solito, i nomi dei parametri di tipo sono lettere maiuscole singole per renderlo facilmente distinguibile dalle variabili java. I nomi dei parametri di tipo più comunemente usati sono:
- E – Element (ampiamente utilizzato da Java Collections Framework, ad esempio ArrayList, Set ecc.)
- K – Key ( Usato in mappa)
- N – Numero
- T – Tipo
- V – Valore (usato in mappa)
- S, U, V ecc. – 2 °, 3 °, 4 ° tipo
Metodo generico Java
A volte non vogliamo che l’intera classe sia parametrizzata, in tal caso possiamo crea il metodo java generics. Poiché il costruttore è un tipo speciale di metodo, possiamo usare anche il tipo generics nei costruttori.
Ecco una classe che mostra un esempio di un metodo generico java.
Notare il metodo isEqual firma che mostra la sintassi per utilizzare il tipo generico nei metodi. Inoltre, nota come utilizzare questi metodi nel nostro programma java. Possiamo specificare il tipo durante la chiamata a questi metodi oppure possiamo invocarli come un metodo normale. Il compilatore Java è abbastanza intelligente da determinare il tipo di variabile da utilizzare, questa funzione è chiamata inferenza del tipo.
Parametri di tipo limitato Java Generics
Supponiamo di voler limitare il tipo di oggetti che possono essere utilizzati nel tipo parametrizzato, ad esempio in un metodo che confronta due oggetti e vogliamo assicurati che gli oggetti accettati siano comparabili. Per dichiarare un parametro di tipo limitato, elenca il nome del parametro di tipo, seguito dalla parola chiave extends, seguito dal suo limite superiore, simile al seguente metodo.
Il l’invocazione di questi metodi è simile al metodo illimitato tranne per il fatto che se proveremo a utilizzare una classe che non è Comparable, genererà un errore in fase di compilazione.
I parametri di tipo limitato possono essere utilizzati con metodi oltre classi e interfacce.
Java Generics supporta anche più limiti, cioè < T extends A & B & C >. In questo caso, A può essere un’interfaccia o una classe. Se A è di classe, B e C dovrebbero essere un’interfaccia. Non possiamo avere più di una classe in più limiti.
Java Generics and Inheritance
Lo sappiamo L’ereditarietà Java ci consente di assegnare una variabile A a un’altra variabile B se A è una sottoclasse di B. Quindi potremmo pensare che qualsiasi tipo generico di A possa essere assegnato al tipo generico di B, ma non è così. Vediamolo con un semplice programma.
Non siamo autorizzati ad assegnare la variabile MyClass < String > a MyClass < Oggetto > variabile perché non sono correlate, infatti MyClass < T > genitore è Object.
Classi generiche Java e sottotipizzazione
Possiamo sottotipolare una classe o un’interfaccia generica estendendola o implementandola. La relazione tra i parametri di tipo di una classe o interfaccia e i parametri di tipo di un’altra è determinata dalle clausole extends e implements.
La relazione di sottotipizzazione viene preservata fintanto che non si cambia l’argomento di tipo, sotto mostra un esempio di più parametri di tipo.
I sottotipi di List < String > può essere MyList < String, Object >, MyList < String, Integer > e così via.
Java Generics Wildcards
Il punto interrogativo (?) È il carattere jolly nei generici e rappresenta un tipo sconosciuto. Il carattere jolly può essere utilizzato come tipo di parametro, campo o variabile locale e talvolta come tipo restituito. Non possiamo utilizzare caratteri jolly durante il richiamo di un metodo generico o la creazione di un’istanza di una classe generica. Nelle sezioni seguenti apprenderemo i caratteri jolly con delimitazione superiore, i caratteri jolly con delimitazione inferiore e l’acquisizione di caratteri jolly.
9.1) I caratteri jolly con delimitazione superiore di Java Generics
vengono usati per rilassare il restrizione sul tipo di variabile in un metodo. Supponiamo di voler scrivere un metodo che restituisca la somma dei numeri nell’elenco, quindi la nostra implementazione sarà qualcosa del genere.
Ora il problema con l’implementazione sopra è che non funzionerà con List of Integers o Double perché sappiamo che List < Integer > e List < I doppi > non sono correlati, questo è quando un carattere jolly delimitato superiore è utile. Usiamo il carattere jolly generics con la parola chiave extends e la classe o l’interfaccia del limite superiore che ci permetterà di passare l’argomento del limite superiore o dei suoi tipi di sottoclassi.
L’implementazione sopra può essere modificata come il programma seguente.
È simile alla scrittura del nostro codice in termini di interfaccia, nel metodo sopra possiamo usare tutti i metodi della classe superiore Number. Si noti che con l’elenco delimitato superiore, non è consentito aggiungere alcun oggetto all’elenco eccetto null. Se proveremo ad aggiungere un elemento all’elenco all’interno del metodo sum, il programma non verrà compilato.
9.2) Java Generics Unbounded Wildcard
A volte abbiamo una situazione in cui desidera che il nostro metodo generico funzioni con tutti i tipi, in questo caso può essere utilizzato un carattere jolly illimitato. È come usare <? extends Object >.
Possiamo fornire List < Stringa > o Elenco < Integer > o qualsiasi altro tipo di argomento Elenco oggetti per metodo printData. Simile all’elenco del limite superiore, non è consentito aggiungere nulla all’elenco.
9.3) Java Generics Lower bounded Wildcard
Supponiamo di voler aggiungere Integer a un elenco di interi in un metodo, possiamo mantenere il tipo di argomento come List < Integer > ma sarà associato a numeri interi mentre List < Number > e List < L’oggetto > può contenere anche numeri interi, quindi possiamo utilizzare un carattere jolly con limite inferiore per ottenere ciò. Usiamo il carattere jolly generics (?) Con la parola chiave super e la classe limite inferiore per raggiungere questo obiettivo.
Possiamo passare il limite inferiore o qualsiasi supertipo di limite inferiore come argomento, in questo caso, il compilatore java consente di aggiungere inferiore tipi di oggetti associati all’elenco.
Sottotipo utilizzando Generics Wildcard
Java Generics Type Erasure
Generics in Java è stato aggiunto per fornire il controllo del tipo in fase di compilazione e non ha alcun uso in fase di esecuzione, quindi il compilatore java utilizza la funzione di cancellazione del tipo per rimuovere tutto il codice di controllo del tipo generico nel codice byte e inserire il casting del tipo se necessario. La cancellazione dei tipi garantisce che non vengano create nuove classi per i tipi parametrizzati; di conseguenza, i generici non incorrono in alcun sovraccarico di runtime.
Ad esempio, se abbiamo una classe generica come di seguito;
Il compilatore Java sostituisce il parametro di tipo limitato T con la prima interfaccia associata, Comparable , come sotto il codice:
Domande frequenti sui generici
12.1) Perché usiamo i generici in Java?
I generici forniscono un forte controllo del tipo in fase di compilazione e riducono il rischio di ClassCastException e casting esplicito di oggetti.
12.2) Che cos’è T in Generics?
Usiamo < T > per creare una classe, un’interfaccia e un metodo generici. La T viene sostituita con il tipo effettivo quando lo usiamo.
12.3) Come funzionano i generics in Java?
Il codice generico garantisce la sicurezza dei tipi. Il compilatore utilizza la cancellazione del tipo per rimuovere tutti i parametri di tipo in fase di compilazione per ridurre il sovraccarico in fase di esecuzione.
Generics in Java – Ulteriori letture
Questo è tutto per i generici in java, java i generici sono un argomento molto vasto e richiedono molto tempo per comprenderli e utilizzarli in modo efficace. Questo post qui è un tentativo di fornire dettagli di base sui generici e su come possiamo usarli per estendere il nostro programma con l’indipendenza dai tipi.