Programmazione Parametrica ( a.k.a. Generics ). Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo.

Slides:



Advertisements
Presentazioni simili
TAV.1 Foto n.1 Foto n.2 SCALINATA DI ACCESSO ALL’EREMO DI SANTA CATERINA DEL SASSO DALLA CORTE DELLE CASCINE DEL QUIQUIO Foto n.3 Foto n.4.
Advertisements

II° Circolo Orta Nova (FG)
1 Le s-espressioni. 2 Un nuovo esempio completo: le s-espressioni Sexpr 4 alberi binari (possibilmente vuoti) che hanno sulle foglie atomi (stringhe)
1 Progettazione gerarchica delle s- espressioni, utilizzando lereditarietà
Interfacce Java.
Capitolo 2 Nozioni fondamentali su Java Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © The McGraw-Hill.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Semantica Operazionale di un frammento di Java: lo stato.
Esercizio 2. Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni di classe.
Sequential Statements. – Il VHDL simula lo svolgersi in parallelo di varie operazioni – Loggetto fondamentale e il PROCESS – Un PROCESS contiene una serie.
Frontespizio Economia Monetaria Anno Accademico
Programmazione Parametrica ( a.k.a. Generics )
XXIV Congresso ACOI 2005 Montecatini Terme Maggio 2005
Virtual CPU - Eniac Dr.ssa Veronica Marchetti
Layouts and Graphics. component - container - layout Un Container contiene [0 o +] Components Il Layout specifica come i Components sono disposti nel.
Esempio: Tombola! Parte seconda.
Unified Modeling Language class C {…} class B extends C {…} Esiste una notazione grafica per mostrare le relazioni di ereditarietà. Object StringC B Tutte.
J0 1 Marco Ronchetti Java Threads & Sincronizzazione.
Sezione: Costruttori Costruttori. Definizione dei costruttori Se per una classe A non scrivo nessun costruttore, il sistema automaticamente crea il costruttore.
prompt> java SumAverage
1 struct Pila { private: int size; int defaultGrowthSize; int marker; int * contenuto; void cresci(int increment); public: Pila(int initialSize) ; Pila();
HDM Information Design notation v.4. HDM Information Design.
Costruzione di Interfacce Lezione 10 Dal Java al C++ parte 1
Ufficio Studi UNIONCAMERE TOSCANA 1 Presentazione di Riccardo Perugi Ufficio Studi UNIONCAMERE TOSCANA Firenze, 19 dicembre 2000.
Astrazioni sul controllo Iteratori. 2 Nuove iterazioni Definendo un nuovo tipo come collezione di oggetti (p. es., set) si vorrebbe disporre anche di.
1 Ultima Lezione del Corso di Fondamenti di Informatica 1 a.a – 06 Ma 29-Nov-2005.
1. Conoscere luso delle collezioni in Java Comprendere le principali caratteristiche nelle varie classi di Collection disponibili Saper individuare quali.
JAVA C import java.util.*; #include <stdio.h>
6.6Ordinamento di Vettori Ordinamento di dati –Applicazione computazionale importante –Virtualmente ogni organizzazione deve ordinare dei dati Enormi quantità
1 Implementazione di Linguaggi 2 PARTE 6 Implementazione di Linguaggi 2 PARTE 6 Massimo Ancona DISI Università di Genova Testo: A.V. Aho, R. Sethi, J.D.Ullman.
Capitolo OD.
2000 Prentice Hall, Inc. All rights reserved. 1 Capitolo 6: Classi e astrazione dati 1.Introduzione 2.Definizione delle strutture 3.Accedere ai membri.
Sottoprogrammi e Unità di Compilazione Nicola Fanizzi Laboratorio - Corso di Programmazione (B) C.d.L. in Informatica DIB - Università degli Studi di Bari.
1 laboratorio di calcolo II AA 2003/04 ottava settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
Progetto di applicazioni grafiche. Disegno di forme complesse Prassi : un classe per ciascuna forma Progetta la forma individuando le componenti base.
Packages. Package: insieme di classi e interfacce in relazione Per formare un package basta inserire la direttiva come prima istruzione nel file sorgente.
Callbacks. Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo.
Programmazione Parametrica ( a.k.a. Generics ). Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo.
Compito desame del Svolgimento della Sezione 5: CONTROLLORI Esempio preparato da Michele MICCIO.
Java Collections.
Sequence. CREARE UNA SEQUENCE CREATE SEQUENCE nome [INCREMENT BY n] [START WITH n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE]
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
La Cooperativa Sociale Le Sagome nasce nel dicembre 2005, grazie ad un progetto finanziato in parte dal fondo sociale europeo, coordinato e guidato da.
JavaScript Lezione 5 Tipizzazione ed operazioni tra tipi diversi Istruzioni di input.
Fondamenti di Informatica Corsi di Laurea in Ingegneria Gestionale Canale AL ESERCITAZIONE 6 ARGOMENTI: LAVORARE CON CLASSI METODI DELLISTANZA, COSTRUTTORI.
ORDINE DI CHIAMATA a 1minuto e 2 minuti PRINCIPALI TEMPI DELLA COMPETIZIONE ORDINE DI CHIAMATA a 1minuto e 2 minuti PRINCIPALI TEMPI DELLA COMPETIZIONE.
Scheda Ente Ente Privato Ente Pubblico. 2ROL - Richieste On Line.
1 Guida per linsegnamento nei corsi per il conseguimento del CERTIFICATO DI IDONEITÀ ALLA GUIDA DEL CICLOMOTORE.
Bando Arti Sceniche. Per poter procedere è indispensabile aprire il testo del Bando 2ROL - Richieste On Line.
24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente,
Ese 2 (del 31 Marzo 2004). Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni.
/ Elementi di C++ Introduzione a ROOT , Laboratorio Informatico ROOT warm up , Laboratorio Informatico Introduzione a.
Multiset. Progettare (specifica con identificazione delle eventuali astrazioni necessarie, incluse eccezioni, e implementazione) del tipo di dato Multiset,
Test con JUnit. zJUnit è un ambiente di test per programmi Java ySviluppato da Kent Beck É possibile usare JUnit allinterno di Eclipse per eseguire i.
1 Simulated multiple inheritance Sandro Pedrazzini Approfondimento Simulated multiple inheritance in Java.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
1 Sky 2 Sky 3 Sky L’Universo Aperto La teoria del Big Bang prevede che, se la densità globale dell’universo non raggiunge un valore di Ωo (Omega Zero)
Collection & Generics in Java
Fondamenti di informatica T-A Esercitazione 7 : Collezioni AA 2012/2013 Tutor : Domenico Di Carlo.
MA COME POSSO PARLARTI, MIO DIO ? Incontri biblici sui SALMI A cura di Antonella Jori Parrocchia di s. Ugo – Roma
Moles and Formula Mass.
JDBC Java DataBase Connectivity SISTEMI ITIS B. CASTELLI Anno Scolastico
1 Acceleratori e Reattori Nucleari Saverio Altieri Dipartimento di Fisica Università degli Studi - Pavia
Customer satisfaction anno 2013 Ospedale di Circolo Fondazione Macchi Varese Presentazione risultati (Febbraio 2014)
ANNI POLIZZA 1 IMPORTO PREMIO UNICO INTERESSE NETTO ANNUO (%) TOTALE INTERESSI (€) POLIZZA 2 IMPORTO PREMIO ANNUO (INDICIZZATO) POLIZZA 3 IMPORTO PREMIO.
Fondamenti di informatica Oggetti e Java Luca Cabibbo Luca Cabibbo – Fondamenti di informatica: Oggetti e Java Copyright © 2004 – The McGraw-Hill Companies.
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
Collection & Generics in Java
Transcript della presentazione:

Programmazione Parametrica ( a.k.a. Generics )

Introduzione ai meccanismi e concetti della programmazione parametrica Generics e relationi di sottotipo wildcards generics e vincoli Implemendaizone di classi e metodi parametrici Supporto per i generics nella JVM

Programmazione polimorfa Polimorfo ~ multiforme, di molti tipi Programmazione polimorfa: creazione di costrutti (classi e metodi) che possono essere utilizzati in modo uniforme su dati di tipo diverso In Java, tradizionalmente ottenuta mediante i meccanismi di sottotipo ed ereditarietà Da Java 1.5. anche mediante i meccanismi di parametrizzazione di tipo (a.k.a. generics)

Variabili di Tipo Le variabili (o parametri) di tipo pemettono di creare astrazioni di tipo Classico caso di utilzzo nelle classi Container E = variabile di tipo astrae (e rappresenta) il tipo delle componenti public class ArrayList { public ArrayList() {... } public void add(E element) {... }... } Continua

Variabili di Tipo Possono essere istanziate con tipi classe o interfaccia Vincolo: tipi che istanziano variabili di tipo non possono essere primitivi (devono essere tipi riferimento) Classi wrapper utili allo scopo ArrayList ArrayList ArrayList // No! ArrayList

Variabili di tipo e controlli di tipo Utilizzare variabili di tipo nella programmazione permette maggiori controlli sulla correttezza dei tipi in fase di compilazione Aumenta quindi la solidità e robustezza del codice Continua

Variabili di tipo e controlli di tipo Un classico caso di utilizzo di containers Il cast è problematico, per vari motivi verboso, fonte di errori a run time Ma necessario per la compilazione e per localizzare leventuale errore a run time Continua List intList = new LinkedList(); intList.add(new Integer(0)); Integer x = (Integer) intList.iterator().next();

Variabili di tipo e controlli di tipo Container generici: più sintetici ed eleganti Compilatore può stabilire un invariante sugli elementi della lista garantire lassenza di errori a run-time in forza di quellinvariante. List intList = new LinkedList (); intList.add(new Integer(0)); Integer x = intList.iterator().next(); Continua

Variabili di tipo e controlli di tipo Ora non è possibile aggiungere una stringa ad intlist:List Le variabili di tipo rendono il codice parametrico più robusto e semplice da leggere e manutenere List intList = new LinkedList (); intList.add(new Integer(0)); Integer x = intList.iterator().next();

Classi parametriche: definizione // nulla di particolare, a parte i parametri // tra parentesi angolate public interface List { void add(E x); Iterator iterator(); } public interface Iterator { F next(); boolean hasNext(); } Un frammento delle interfacce List e Iterator nel package java.util.*

Classi parametriche: uso Quando utilizziamo un tipo parametrico, tutte le occorrenze dei parametri formali sono rimpiazzate dallargomento (parametro attuale) Meccanismo simile a quello del passaggio dei parametri in un metodo Diversi usi generano tipi diversi Ma... classi parametriche compilate una sola volta danno luogo ad un unico file.class

Sintassi: uso GenericClassName Esempio: ArrayList HashMap Scopo: Fornire tipo specifici per ciascuna delle variabili di tipo introdotte nella dichiarazione

public class Pair { public Pair(T firstElement, S secondElement) { first = firstElement; second = secondElement; } public T getFirst() { return first; } public S getSecond() { return second; } private T first; private S second; } Esempio: Pair Una semplice classe parametrica per rappresentare coppie di oggetti Continua

Esempio: Pair Una semplice classe parametrica per rappresentare coppie di oggetti: I metodi getFirst e getSecond restituiscono il primo e secondo elemento, con i tipi corrispondenti Pair result = new Pair ("Harry Hacker", harrysChecking); String name = result.getFirst(); BankAccount account = result.getSecond();

Variabili di tipo: convenzioni VariabileSignificato Inteso ETipo degli elementi in una collezione KTipo delle chiavi in una mappa VTipo dei valori in una mappa T,S,UTipi generici

Esempio: LinkedList public class LinkedList {... public E removeFirst() { if (first == null) throw new NoSuchElementException(); E element = first.data; first = first.next; return element; }... private Node first; private class Node { E data; Node next; } } Continua

Esempio: LinkedList Notiamo la struttura della classe ausiliaria che specifica la struttura dei nodi Se la classe è interna, come in questo caso, non serve alcun accorgimento allinterno di Node possiamo utilizzare il tipo E, il cui scope è tutta la classe Se invece la classe è esterna, dobbiamo renderla generica public class ListNode

Esempio: LinkedList private class Node { F data; Node next; } public class LinkedList {... public E removeFirst() { if (first == null) throw new NoSuchElementException(); E element = first.data; first = first.next; return element; }... private Node first; } Continua

File LinkedList.java 001: import java.util.NoSuchElementException; 002: 003: /** 004: A linked list is a sequence of nodes with efficient 005: element insertion and removal. This class 006: contains a subset of the methods of the standard 007: java.util.LinkedList class. 008: */ 009: public class LinkedList 010: { 011: /** 012: Constructs an empty linked list. 013: */ 014: public LinkedList() 015: { 016: first = null; 017: } 018: Continua

File LinkedList.java 019: /** 020: Returns the first element in the linked list. the first element in the linked list 022: */ 023: public E getFirst() 024: { 025: if (first == null) 026: throw new NoSuchElementException(); 027: return first.data; 028: } 029: 030: /** 031: Removes the first element in the linked list. the removed element 033: */ 034: public E removeFirst() 035: { Continua

File LinkedList.java 036: if (first == null) 037: throw new NoSuchElementException(); 038: E element = first.data; 039: first = first.next; 040: return element; 041: } 042: 043: /** 044: Adds an element to the front of the linked list. element the element to add 046: */ 047: public void addFirst(E element) 048: { 049: Node newNode = new Node(element,first); 052: first = newNode; 053: } Continua

File LinkedList.java 054: 055: /** 056: Returns an iterator for iterating through this list. 057: 058: */ 059: public ListIterator listIterator() 060: { 061: return new LinkedListIterator(); 062: } 063: 064: private Node first; 065: 066: private class Node 067: { 068: E data; 069: Node next; 070: } 071: Continua

LinkedListIterator La definiamo come classe interna di LinkedList Implements linterfaccia ListIterator Ha accesso al campo first e alla classe interna Node

Classe LinkedListIterator 072: private class LinkedListIterator implements ListIterator 073: { 074: /** 075: Costruisce un iteratore posizionato sul primo 076: elemento della lista 077: */ 078: public LinkedListIterator() 079: { 080: last = null; // ultimo nodo visitato 081: previous = null; // precedente a position 082: } 083: Continua

LinkedListIterator – next() 084: /** 085: Posizione literatore sul prossimo. il prossimo elemento 087: */ 088: public E next() 089: { 090: if (!hasNext()) 091: throw new NoSuchElementException(); 092: previous = last; // Remember for remove 093: 094: if (last == null) 095: last = first; 096: else 097: last = last.next; 098: 099: return last.data; 100: } 101: 102: Continua

LinkedListIterator – hasNext() 102: /** 103: Testa se cè un elemento dopo lultimo 104: visitato. true se esiste un elemento dopo 106: lultimo visitato 107: */ 108: public boolean hasNext() 109: { 110: if (last == null) 111: return first != null; 112: else 113: return last.next != null; 114: } 115: 116: Continua

LinkedListIterator – add() 117: /** Aggiunge un elemento dopo last e sposta 118: literatore sul prossimo elemento. 119: */ 121: public void add(E element) 122: { 123: if (last == null) 124: { 125: addFirst(element); last = first; 127: } 128: else 129: { 130: Node newNode = new Node(); 131: newNode.data = element; 132: newNode.next = last.next;// (1) 133: last.next = newNode; // (2) 134: last = newNode; // (3) 135: } 136: previous = last; // (4) 137: } Continua

LinkedListIterator – add() last

LinkedListIterator – remove() 140: /** Rimuove lelemento puntato da last. Può essere 141: invocato solo dopo una chiamata a next() 142: */ 143: public void remove() 144: { 145: if (previous == last) 146: throw new IllegalStateException(); 147: 148: if (last == first) 149: { 150: removeFirst(); 151: } 152: else 153: { 154: previous.next = last.next; // (1) 155: } 156: last = previous; // (2) 157: } Continua

LinkedListIterator –remove() last

Classe LinkedListIterator 159: /** 160: Sets the last traversed element to a different 161: value. element the element to set 163: */ 164: public void set(E element) 165: { 166: if (position == null) 167: throw new NoSuchElementException(); 168: position.data = element; 169: } 170: 171: private Node position; 172: private Node previous; 173: } // end LinkedListIterator 174: } // end LinkedList

File ListIterator.java 01: /** 02: A list iterator allows access of a position in a linked 03: list. This interface contains a subset of the methods 04: of the standard java.util.ListIterator interface. The 05: methods for backward traversal are not included. 06: */ 07: public interface ListIterator 08: { 09: /** 10: Moves the iterator past the next element. the traversed element 12: */ 13: E next(); 14: 15: /** 16: Tests if there is an element after the iterator 17: position. Continua

File ListIterator.java true if there is an element after the iterator 19: position 20: */ 21: boolean hasNext(); 22: 23: /** 24: Adds an element before the iterator position 25: and moves the iterator past the inserted element. element the element to add 27: */ 28: void add(E element); 29: 30: /** 31: Removes the last traversed element. This method may 32: only be called after a call to the next() method. 33: */ Continua

File ListIterator.java 34: void remove(); 35: 36: /** 37: Sets the last traversed element to a different 38: value. element the element to set 40: */ 41: void set(E element); 42: }

Generics e sottotipi Consideriamo La prima istruzione è sicuramente legale, la seconda è più delicata … Number è una classe astratta che ha Integer, Double e altre classi wrapper come sottotipi Per capire se la seconda istruzione sia da accettare come legale continuiamo con lesempio … Continua List li = new ArrayList (); List ln = li;

Generics e sottotipi Come si vede abbiamo un problema nella terza istruzione inseriamo un Double (via auto- boxing, ricordate?) nella quarta estraiamo un Integer ! Il vero problema è nella seconda istruzione soluzione: errore di compilazione per lassegnamento al secondo Continua List li = new ArrayList (); List ln = li; ln.add(3.14); Integer i = li.get(0); // uh oh...

Generics e sottotipi In generale, dati due tipi A e B, ed tipo generico C abbiamo che: Quindi, per le stesse ragioni di prima Continua A B NON implica C C Set NON è sottotipo di Set

Generics e sottotipi Le limitazione sulle relazioni di sottotipo sono contro-intuitive uno degli aspetti più complessi dei generics Non solo … sono spesso anche troppo restrittive illustriamo con un esempio Continua

Generics e sottotipi Un metodo che stampa gli elementi di una collezione Versione tradizionale Continua void printCollection(Collection c) { Iterator i = c.iterator(); for (k = 0; k < c.size(); k++) { System.out.println(i.next()); }

Generics e sottotipi Stampa degli elementi di una collezione Versione generics: primo tentativo utile solo per Collection non per qualsiasi collezione Collection non è il supertipo di tutte le collezioni Continua void printCollection(Collection c) { for (Object e:c) System.out.println(e); }

Wildcards Stampa degli elementi di una collezione Versione generics: secondo tentativo Collection è il supertipo di tutte le Collections la wildcard ? indica un qualche tipo, non specificato Continua void printCollection(Collection c) { for (Object e:c) System.out.println(e); }

Wildcards Possiamo estrarre gli elementi di c al tipo Object Corretto perché, qualunque sia il loro vero tipo, sicuramente è sottotipo di Object Continua void printCollection(Collection c) { for (Object e:c) System.out.println(e); }

Wildcards Continua Collection c = new ArrayList (); c.add(new String()); // errore di compilazione! Daltra parte … visto che non sappiamo esattamente quale tipo indica ?, non possiamo assegnare valori

Date un esempio di codice che causerebbe errore in esecuzione se permettessimo di aggiungere elementi a Collection Domanda

Lultima istruzione invocherebbe intValue() sul primo elemento di ci ma quellelemento ha tipo String … In realtà il compilatore anticipa lerrore, segnalando il problema sulla add() Risposta Collection ci = new ArrayList ; Colletion c = ci; c.add(a string); // non compila ci.get(0).intValue();

Wilcards con vincoli ( bounded ) Shapes : un esempio classico public abstract class Shape { public abstract void draw(Graphics g); } public class Circle extends Shape { private int x, y, radius; public void draw(Graphics g) {... } } public class Rectangle extends Shape { private int x, y, width, height; public void draw(Graphics g) {... } } Continua

Wilcards con vincoli ( bounded ) Graphics e il metodo draw() Solito problema: drawAll() non può essere invocato su una List public class Graphics { // disegna una shape public void draw(Shape s) { s.draw(this); } // disegna tutte le shapes di una lista public void drawAll(List shapes) { for (Shape s:shapes) s.draw(this) }... } Continua

Bounded Wilcards Quello che ci serve è un metodo che accetti liste di qualunque (sotto) tipo di Shape List bounded wildcard indica un tipo sconosciuto, sottotipo di Shape il bound può essere qualunque tipo riferimento (classe o interfaccia) Ora il metodo ha la flessibilità necessaria e desiderata void drawAll(List shapes) {... } Continua

Bounded Wilcards Graphics e il metodo draw() public class Graphics { // disegna una shape public void draw(Shape s) { s.draw(this); } // disegna tutte le shapes di una lista public void drawAll(List shapes) { for (Shape s:shapes) s.draw(this) }... } Continua

Bounded Wilcards Daltra parte, cè sempre un prezzo da pagare Il solito vincolo … Non possiamo modificare strutture con questi tipi [ perché? ] void addRectangle(List shapes) { // errore di compilazione shapes.add(new Rectangle()); }

Metodi che dipendono da una variabile di tipo Possono essere definiti allinterno di qualunque classe, generica o meno N.B. Evitiamo List perché List renderebbe il metodo poco utile (non utilizzabie su liste arbitrarie) /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static void array2List(Object[] a, List l){... } Metodi Generici Continua

Metodi Generici Al solito però non possiamo aggiungere elementi ad una struttura (o modificare) con elementi di tipo wildcard /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static void array2List(Object[] a, List l) { for (Object o : a) l.add(o) // compiler error } Continua

Metodi Generici Soluzione: rendiamo il metodo parametrico possiamo invocare questo metodo con una qualunque lista il cui tipo sia supertipo del tipo base dellarray purché sia un tipo riferimento /* trasforma un array in una lista, copiando * tutti gli elementi di a in l */ static void array2List(T[] a, List l) { for (T o : a) l.add(o) }

Invocazione di metodi generici Nellinvocazione di un metodo generico non è necessario passare largomento di tipo il compilatore inferisce il tipo, se esiste, dai tipi degli argomenti del metodo

Invocazione di metodi generici Continua Object[] oa = new Object[100]; Collection co = new ArrayList (); fromArrayToCollection(oa, co); // T = Object (inferito) String[] sa = new String[100]; Collection cs = new ArrayList (); fromArrayToCollection(sa, cs); // T = String (inferito) fromArrayToCollection(sa, co); // T = Object (inferito) Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection cn = new ArrayList (); fromArrayToCollection(ia, cn); // T = Number (inferito) fromArrayToCollection(fa, cn); // T = Number (inferito) fromArrayToCollection(na, cn); // T = Number (inferito) fromArrayToCollection(na, co); // T = Object (inferito) fromArrayToCollection(na, cs); // compiler error

Wildarcds vs variabili di tipo Ci sono situazioni in cui è possibili usare equivalentemente wildcards e variabili di tipo. Nella libreria Collection troviamo Continua interface Collection { public boolean containsAll(Collection c); public boolean addAll(Collection c);... }

Wildarcds vs variabili di tipo Queste specifiche possono essere espresse equivalentemente con metodi parametrici Il secondo metodo è parametrico in qualunque sottotipo di E i bounds si possono utilizzare anche con variabili, non solo con wildcards Continua interface Collection { public boolean containsAll(Collection c); public boolean addAll(Collection c);... }

Wildcards e variabili di tipo possono coesistere Notiamo la dipendenza tra i tipi dei due parametri: il tipo della sorgente deve essere un sottotipo del tipo della destinazione Wildarcds vs variabili di tipo Continua interface Collection { public static void copy(List dest, List src)... }

Potremmo analogamente riformulare in modo da evitare le wildcards Come scegliere tra le due soluzioni? Wildarcds vs variabili di tipo Continua interface Collection { public static void copy( dest, List src)... }

In generale, preferiamo le wildcards quando entrambe le soluzioni sono possibili Possiamo darci la seguente rule of thumb se una variabile di tipo ha una unica occorrenza nella specifica di un metodo e il tipo non è il target di un operazione di modifica utilizziamo una wildcard al posto della variabile Wildarcds vs variabili di tipo

Variabili di Tipo e Bounds Abbiamo visto che possiamo definire bounds anche per variabili di tipo (non solo wildcards) Un caso paradigmatico public static > T max(Collection coll) { T candidate = coll.iterator().next(); for (T e : coll) if candidate.compareTo(e) < 0) candidate = e; return candidate; }

Variabili di Tipo e Bounds Il bound su una variabile impone vincoli sulla variabile, determinando quali metodi possono essere utilizzati su valori del tipo variabile Qui il bound è ricorsivo: informa che i valori con cui operiamo forniscono un metodo compareTo() che gli argomenti del metodo devono essere dello stesso tipo dei valori public static > T max(T max(List coll)

Generics e erasure I tipi generici sono significativi a compile-time La JVM opera invece con tipi raw Il tipo raw è ottenuto da un tipo generico mediante un processo detto erasure che rimuove le variabili di tipo il bycode generato da un tipo generico è lo stesso che viene generato dal corrispondente tipo raw.

Generics e erasure Generano lo stesso bytecode List words = new ArrayList (); words.add(hi); words.add(there); String welcome = words.get(0) + words.get(1); List words = new ArrayList(); words.add(hi); words.add(there); String welcome = (String)words.get(0) + (String)words.get(1);

Generics e erasure Cast-iron guarantee i cast impliciti che vengono aggiunti dalla compilazione di codice generico non falliscono mai.