Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
1PR22017-2018
PROGRAMMAZIONE213.JavaGenerics
JavaInterfaceeastrazione
interface ListOfNumbers { boolean add(Number elt); Number get(int index); } interface ListOfIntegers { boolean add(Integer elt); Integer get(int index); } …eListOfStringse…//Necessarioastrarresui,piinterface List<E> { boolean add(E n); E get(int index); }
2
Usiamoi,pi!!! List<Integer> List<Number> List<String> List<List<String>> …
PR22017-2018
Parametrieparametridi;po
interface ListOfIntegers { boolean add(Integer elt); Integer get(int index); } interface List<E> { boolean add(E elt); E get(int index); }
3
• Dichiarazionedelparametroformale
• Istanziatoconunaespressionechehail;porichiesto(lst.add(7))
• Tipodiadd:Integer→boolean
• Dichiarazionediunparametrodi;po• Istanziabileconunqualunque;po
• List<String>,etc.
PR22017-2018
Variabilidi;po
class NewSet<T> implements Set<T> { // rep invariant: // non-null, contains no duplicates // ... List<T> theRep; T lastItemInserted; ... }
4
Dichiarazione
Use U;lizzo
PR22017-2018
Dichiarareclassigeneriche
class Name<TypeVar1, …, TypeVarN> {…} interface Name<TypeVar1, …, TypeVarN> {…}
o convenzionistandardTperType,EperElement,KperKey,VperValue,…
Istanziareunaclassegenericasignificafornireunvaloredi;po Name<Type1, …, TypeN>
5 PR22017-2018
Istanziare;pi
boolean add1(Object elt); boolean add2(Number elt); add1(new Date( )); // OK add2(new Date( )); // compile-time error
interface List1<E extends Object> {…} interface List2<E extends Number> {…}
List1<Date> // OK, Date è un sottotipo di Object
List2<Date> // compile-time error, Date non è // sottotipo di Number
6
Limitesuperioregerarchia
PR22017-2018
VisioneeffeOvadeigenerici
class Name<TypeVar1 extends Type1, …, TypeVarN extends TypeN> {…}
o (analogoperleinterfacce)o (intuizione:Objectèillimitesuperioredidefaultnellagerarchiadei;pi)
Istanziazioneiden;ca Name<Type1, …, TypeN>
• Macompile-,meerrorseil;pononèunsoSo-;podellimitesuperioredellagerarchia
7 PR22017-2018
Usiamolevariabilidi;po
SipossonoeffeSuaretuSeleoperazionicompa;biliconillimitesuperioredellagerarchia
– conceSualmentequestocorrispondeaforzareunapre-condizionesullaistanziazionedel;po
class List1<E extends Object> { void m(E arg) { arg.asInt( ); // compiler error, E potrebbe
// non avere l’operazione asInt } }
class List2<E extends Number> { void m(E arg) { arg.asInt( ); // OK, Number e tutti i suoi // sotto-tipi supportano asInt } }
8 PR22017-2018
Vincolidi;po
<TypeVar extends SuperType> o upperbound:vabeneilsuper-;poounodeisuoisoSo-;pi
<TypeVar extends ClA & InterB & InterB & ... > o mul,pleupperbounds
<TypeVar super SubType> o lowerbound:vabeneilsoSo-;poounoqualunquedeisuoisuper-;pi
Esempio// strutture di ordine su alberi public class TreeSet<T extends Comparable<T>> { ... }
9 PR22017-2018
Esempiodimetodiausiliari
class Utils { static double sumList(List<Number> lst) { double result = 0.0; for (Number n : lst) result += n.doubleValue( ); return result; } static Number choose(List<Number> lst) { int i = ... // numero random < lst.size return lst.get(i); }}
10 PR22017-2018
Soluzioneefficace
class Utils { static <T extends Number> double sumList(List<T> lst) { double result = 0.0; for (Number n : lst) // T also works result += n.doubleValue(); return result; }
static <T> T choose(List<T> lst) { int i = … // random number < lst.size return lst.get(i); }}
11
Dichiararenellafirmaivincolisui;pi
PR22017-2018
Metodigenerici
• Metodichepossonousarei;pigenericidelleclassi
• Possonodichiarareancheiloro;pigenerici
• Leinvocazionidimetodigenericidevonoobbligatoriamenteistanziareiparametridi;poo sta;camente:unaformadiinferenzadi;po
12 PR22017-2018
Esempiodi;poistanziatodallaclasse
public class InsertionSort<T extends Comparable<T>> { public void sort(T[ ] x) {
T tmp; for (int i = 1; i < x.length; i++) {
// invariant: x[0],...,x[i-1] sorted tmp = x[i]; int j;
for (j = i; j > 0 && x[j-1].compareTo(tmp) > 0; j--)
x[j] = x[j-1]; x[j] = tmp; } } }
13 PR22017-2018
IgenericielanozionedisoSo-;po
• IntegerèunsoSo-;podiNumber
• List<Integer>èunsoSo-;podiList<Number>?
14
Number
Integer
List<Number>
List<Integer>?
PR22017-2018
QualisonoleregolediJava?
AncheseType2èunsoSo-;podiType3,seidue;pisonodiversialloraType1<Type2>nonèunsoSo-;podiType1<Type3>Formalmente:lanozionedisoSo-;pousatainJavaèinvarianteperleclassigeneriche
15 PR22017-2018
Esempi(daJava)
• TipiesoSo-;pio IntegerèunsoSo;podiNumbero ArrayList<E>èunsoSo-;podiList<E>o List<E>èunsoSo-;podiCollec;on<E>
• Mao List<Integer>nonèunsoSo-;podiList<Number>
16 PR22017-2018
List<Number>eList<Integer>
interface List<T> { boolean add(T elt); T get(int index); } typeList<Number>has boolean add(Number elt); Number get(int index); typeList<Integer>has boolean add(Integer elt); Integer get(int index); List<Number>nonèunsuper-;podiList<Integer>
17
Number
Integer
PR22017-2018
Unadiscussione(percapirelaricercanelseSore)
interface List<T> { T get(int index); } typeList<Number>has Number get(int index); typeList<Integer>has Integer get(int index); LanozionedisoSo-;pocovariantesarebbecorreSa
o List<Integer>soSo-;podiList<Number>
SfortunatamenteJavanonadoSaquestasoluzione
18
Number
Integer
PR22017-2018
Alloraparliamoanchedicontravarianza
interface List<T> { boolean add(T elt); } typeList<Number>has boolean add(Number elt); typeList<Integer>has boolean add(Integer elt); LanozionedisoSo-;pocontravariantesarebbealtreSantocorreSa
o List<Number>èsoSo-;podiList<Integer>
MaJava...
19
Number
Integer
PR22017-2018
AltriaspeO
• List<Integer>eList<Number>nonsonocorrela;dallanozionedisoSo-;po
• TuSavia,sulprimoargomentolanozionedisoSo-;posuigenericifunzionacomeunoseloaspeSaancheinJava
• Esempio:assumiamocheLargeBagextendsBag,allorao LargeBag<Integer>èunsoSo-;podiBag<Integer> o LargeBag<Number>èunsoSo-;podiBag<Number> o LargeBag<String>èunsoSo-;podiBag<String> o …
20 PR22017-2018
addAll
interface Set<E> {// Aggiunge a this tutti gli elementi di c
// (che non appartengono a this) void addAll(??? c);}
Qualeèilmiglior;poperilparametroformale?o Ilpiùampiopossibile…o …chepermeSediavereimplementazionicorreSe
21 PR22017-2018
addAll
interface Set<E> { // Aggiunge a this tutti gli elementi di c // (che non appartengono a this) void addAll(??? c);}
Unaprimasceltaèvoid addAll(Set<E> c); TropporestriOvo
o unparametroaSualedi;poList<E>nonsarebbepermesso,eciòèspiacevole…
22 PR22017-2018
addAll
interface Set<E> { // Aggiunge a this tutti gli elementi di c // (che non appartengono a this) void addAll(??? c);}
Secondotenta;vo: void addAll(Collection<E> c);
TropporestriOvoo ilparametroaSualedi;poList<Integer>perSet<Number>
nonvabeneancheseaddAllhasolobisognodileggeredacenondimodificarlo!!!
o questaèlaprincipalelimitazionedellanozionediinvarianzaperigenericiinJava
23 PR22017-2018
addAll
interface Set<E> { // Aggiunge a this tutti gli elementi di c // (che non appartengono a this) void addAll(??? c);}
Proviamoancora <T extends E> void addAll(Collection<T> c);
Ideabuona:unparametrogenericomavincolatoo possoavereunparametroaSualedi;poList<Integer>perSet<Number>
o addAllnonpuòvederenell’implementazioneil;poT,sasolocheèunsoSo-;podiE,enonpuòmodificarelacollec;onc
24 PR22017-2018
Altroesempio
<T> void copyTo(List<T> dst, List<T> src) { for (T t : src) dst.add(t); }
Lasoluzionevabene,maancorameglio <T1, T2 extends T1> void copyTo(List<T1> dst, List<T2> src) { for (T2 t : src) dst.add(t); }
25 PR22017-2018
Wildcard
Sintassidellewildcardo ? extends Type,soSo-;pononspecificatodel;poType o ?notazionesemplificataper? extends Object o ? super Type,super-;pononspecificatodel;poType
wildcard=unavariabiledi;poanonimao ?;pononconosciutoo siusanolewildcardquandosiusaun;poesaSamenteunavoltama
nonsiconosceilnomeo l’unicacosachesisaèl’unicitàdel;po
26 PR22017-2018
Esempi
interface Set<E> { void addAll(Collection<? extends E> c); }
o maggiormenteflessibilerispeSoavoid addAll(Collection<E> c);
o espressivacome <T extends E> void addAll(Collection<T> c);
27 PR22017-2018
ProducerExtends,ConsumerSuper
Quandosiusanolewildcard?o siusa? extends TneicasiincuisivoglionooSeneredeivalori(da
unproduSoredivalori)o siusa? super Tneicasiincuisivoglionoinserirevalori(inun
consumatore)o nonvannousate(bastaT)quandosioSengonoesiproduconovalori
<T> void copy(List<? super T> dst, List<? extends T> src);
28 PR22017-2018
?vsObject
?Tipopar;colareanonimovoid printAll(List<?> lst) {…}
QualedifferenzatraList<?>eList<Object>?o possiamoistanziare?conun;poqualunque:Object,String,…o List<Object>èpiùrestriOvo:List<String>nonvabene
QualedifferenzatraList<Foo>eList<? extends Foo>?o nelsecondocasoil;poanonimoèunsoSo-;posconosciutodiFoo
List<? extends Animal> puòmemorizzareGiraffemanonancheZebre
29 PR22017-2018
Rawtypes
• Conrawtypesiindicaunaclasse/interfacciasenzanessunargomentodi;po(legacycode)
30
Vector<Integer> intVec = new Vector<Integer>(); Vector rawVec = new Vector(); // OK
Vector<String> stringVec = new Vector<String>(); Vector rawVec = stringVec; // OK
Vector rawVec = new Vector(); // rawVector is a raw type of Vector<T>
Vector<Integer> intVector = rawVector; // warning: unchecked conversion
PR22017-2018
Inferenzadi;po
• Inferenza:capacitàdicontrollareuna invocazionedimetodoeladichiarazionedimetodoassociataalfinedideterminareil;po più specifico, in accordo ai vincoli di ;po presen;, cherendeilmetodoeffeOvamenteinvocabile
31
class MyClass<S> { <T> MyClass(T t) { ... } }
new MyClass<Integer>("")
MyClass<Integer> myObject = new MyClass<>("")
diamondnota;on
PR22017-2018
Ancoral’inferenzadi;po
32
static <T> List<T> emptyList();
List<String> listOne = Collections.<String>emptyList(); List<String> listOne = Collections.emptyList();
void processStringList(List<String> stringList) { ... }
processStringList(Collections.<String>emptyList());
processStringList(Collections.emptyList());
metodoinCollec;ons
obbligatorioinJava7Java8inferiscedal;podelparametro
PR22017-2018
Javaarray
SappiamobenecomeoperarecongliarrayinJava…Vero?Analizziamoquestaclasse
class Array<T> { public T get(int i) { … "op" … } public T set(T newVal, int i) { … "op" … }} Domanda:seType1èunsoSo-;podiType2,cherelazioneesistetraType1[]eType2[]??
33 PR22017-2018
Sorpresa!
• SappiamocheperigenericilanozionedisoSo;poèinvariante,pertantoancheseType1èunsoSo-;podiType2,i;piType1[]eType2[]nondovrebberoesserecorrela;
• MaJavahadellepeculiarità:seType1èunsoSo-;podiType2,alloraType1[]èunsoSo-;podiType2[]– Java(eC#)hafaSoquestasceltaprimadell’introduzionedeigenerici– cambiarlaoraèunpo’troppoinvasivoperipigriprogrammatoriJava
(commentoobbligatoperchifaricercasuiprincipideilinguaggidiprogrammazione)
34 PR22017-2018
Cisonoanchecose“buone”
Gliinglesidicono:“Programmersdookaystuff”void maybeSwap(LibraryHolding[ ] arr) { if(arr[17].dueDate( ) < arr[34].dueDate( )) // … swap arr[17] and arr[34] } // cliente Book[ ] books = …; maybeSwap(books); // usa la covarianza degli array
35
LibraryHolding
Book CD
PR22017-2018
Mapuòandaremale
void replace17(LibraryHolding[ ] arr, LibraryHolding h) { arr[17] = h; }
// il solito cliente Book[] books = …; LibraryHolding theWall = new CD("Pink Floyd", "The Wall", … ); replace17(books, theWall); Book b = books[17]; // contiene un CD b.getChapters( ); // problema!!
36 PR22017-2018
LibraryHolding
Book CD
LesceltediJava
• Il;podinamicoèunsoSo-;podiquellosta;coo violatonelcasodiBook b
• LasceltadiJavao ogniarray“conosce”ilsuo;podinamico(Book[ ])o modificare(arun-;me)conunsuper-;podeterminaArrayStoreException
• pertantoreplace17sollevaunaeccezioneo EveryJavaarray-updateincludesrun-,mecheck
! (dallaspecificadellaJVM)o Morale:fateaSenzioneagliarrayinJava
37 PR22017-2018
Toogoodtobetrue:typeerasure
TuOi;pigenericisonotrasforma;inObjectnelprocessodicompilazione
o mo;vo:backward-compa;bilityconilcodicevecchioo morale:arun-;me,tuSeleistanziazionigenerichehannolostesso;poList<String> lst1 = new ArrayList<String>( ); List<Integer> lst2 = new ArrayList<Integer>( ); lst1.getClass( ) == lst2.getClass( ) // true
38 PR22017-2018
Genericiecas;ng
List<?> lg = new ArrayList<String>( ); // ok List<String> ls = (List<String>) lg; // warning
Dalladoc.Java:“Compilergivesanuncheckedwarning,sincethisissomethingtherun-;mesystemwillnotcheckforyou”Problema public static <T> T badCast(T t, Object o){
return (T) o; // unchecked warning }
39 PR22017-2018
equals
class Node<E> { ... @Override public boolean equals(Object obj) { if (!(obj instanceof Node<E>)) return false; Node<E> n = (Node<E>) obj; return this.data( ).equals(n.data( )); } ... }
40
Erasure:il;podell’argomentononesistearun-;me
PR22017-2018
equals
class Node<E> { ... @Override public boolean equals(Object obj) { if (!(obj instanceof Node<?>)) return false; Node<E> n = (Node<E>) obj; return this.data( ).equals(n.data( )); } ... }
41
Erasure:arun-;menonsisacosasiaE
PR22017-2018
Tips(dastackoverflow)
• Startbywri;ngaconcreteinstan;a;ono getitcorrect(tes;ng,reasoning,etc.)o considerwri;ngasecondconcreteversion
• Generalizeitbyaddingtypeparameterso thinkaboutwhichtypesarethesameordifferento thecompilerwillhelpyoufinderrors
42 PR22017-2018
JavaGenerics(JG)
• Ilcompilatoreverifical’u;lizzocorreSodeigenerici
• Iparametridi;posonoelimina;nelprocessodicompilazioneeil“classfile”risultantedallacompilazioneèunnormaleclassfilesenzapoliformismoparametrico
PR22017-2018 43
Esempio
class Vector<T> { T[] v; int sz; Vector() { v = new T[15]; sz = 0; } <U implements Comparer<T>> void sort(U c) { … c.compare(v[i], v[j]); … } } … Vector<Button> v; v.addElement(new Button()); Button b = v.elementAt(0);
class Vector { Object[] v; int sz; Vector() { v = new Object[15]; sz = 0; } void sort(Comparer c) { … c.compare(v[i], v[j]); … } } … Vector v; v.addElement(new Button()); Button b =
(Button)v.elementAt(0);
PR22017-2018 44
Considerazioni
• JGaiutanoamigliorareilpolimorfismodellasoluzione
• Limiteprincipale:il;poeffeOvoèpersoarun-;meacausadellatypeerasure
• TuSeleistanziazionisonoiden;ficate• EsistonoaltreimplementazionideigenericiperJava
PR22017-2018 45
AltrigenericiperJava
JG/PizzaBracha,Odersky,
Stoutamire,Wadler
NextGenCartwright,
Steele
PolyJBank,Liskov,
Myers
Agesen,Freund,Mitchell
GenericCLRKennedy,Syme
Parameterizedtypes!
+bounds!
+bounds!
+constraints!
+bounds!
+bounds
Polymorphicmethods ! ! " " !
Typecheckingatpointofdefini;on ! ! ! " !Non-referenceinstan;a;ons " " ! ! !
Exactrun-;metypes" ! ? ! !
Polymorphicvirtualmethods " ! " " !
Typeparametervariance " ! " " "
System
Feature