301AA - Advanced Programming [AP-2017] -...
Transcript of 301AA - Advanced Programming [AP-2017] -...
![Page 1: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/1.jpg)
301AA-AdvancedProgramming[AP-2017]
Lecturer:[email protected]:[email protected]
DepartmentofComputerScience,PisaAcademicYear2017/18
AP-2017-14: JavaGenerics
![Page 2: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/2.jpg)
Outline
• Javagenerics• Typebounds• Genericsandsubtyping• Covariance,contravarianceinJavaandotherlanguages
• SubtypingandarraysinJava• Wildcards• Typeerasure• LimitaQonsofgenerics
2
![Page 3: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/3.jpg)
ClassificaQonofPolymorphism
Polymorphism
Universal
Ad hoc
Parametric
Inclusion
Overloading
Coercion Implicit
Bounded
Overriding
Explicit
Covariant
Invariant
Contravariant
Bounded
![Page 4: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/4.jpg)
JavaGenerics
• Classes,Interfaces,Methodscanhavetypeparameters
• ThetypeparameterscanbeusedarbitrarlyinthedefiniQon
• TheycanbeinstanQatedbyprovidingarbitrary(reference)typearguments
• WediscussonlyafewissuesaboutJavagenerics…
4
List<Integer> List<Number> List<String> List<List<String>> …
interface List<E> { boolean add(E n); E get(int index); }
ExplicitParametricPolymorphism
TutorialsonJavagenerics:https://docs.oracle.com/javase/tutorial/java/generics/index.html!http://thegreyblog.blogspot.it/2011/03/
! !java-generics-tutorial-part-i-basics.html!
![Page 5: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/5.jpg)
Genericmethods
• Methodscanusethetypeparametersoftheclasswheretheyaredefined,ifany
• Theycanalsointroducetheirowntypeparameters
public static <T> T getFirst(List<T> list)!
!• InvocaQonsofgenericmethodsmustinstanQateall
typeparameters,eitherexplicitlyorimplicitly– Aformoftypeinference
5
![Page 6: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/6.jpg)
BoundedTypeParameters interface List<E extends Number> { void m(E arg) { arg.asInt(); // OK, Number and its subtypes // support asInt() } }
• OnlyclassesimplemenQngNumbercanbeusedastypearguments
• Methoddefinedinthebound(Number)canbeinvokedonobjectsofthetypeparameter
6
![Page 7: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/7.jpg)
TypeBounds<TypeVar extends SuperType> – upperbound;SuperTypeandanyofitssubtypeareok.
<TypeVar extends ClassA & InterfaceB & InterfaceC & …> – Mul4pleupperbounds
<TypeVar super SubType> – lowerbound;SubTypeandanyofitssupertypeareok
• TypeboundsformethodsguaranteethatthetypeargumentsupportstheoperaQonsusedinthemethodbody
• UnlikeC++whereoverloadingisresolvedandcanfailaderinstanQaQngatemplate,inJavatypecheckingensuresthatoverloadingwillsucceed
7
![Page 8: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/8.jpg)
Agenericalgorithmwithtypebounds
8
public static <T> int countGreaterThan(T[] anArray, T elem) {! int count = 0;! for (T e : anArray)! if (e > elem) // compiler error! ++count;! return count;!}!
public interface Comparable<T> { !// classes implementing! public int compareTo(T o); !// Comparable provide a !} ! !// default way to compare their objects!
public static <T extends Comparable<T>> !! ! ! !int countGreaterThan(T[] anArray, T elem) {!
int count = 0;! for (T e : anArray)! if (e.compareTo(elem) > 0) !// ok, it compiles! ++count;! return count;!}!
![Page 9: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/9.jpg)
Genericsandsubtyping
• IntegerissubtypeofNumber!
• IsList<Integer>subtypeofList<Number>?
• NO!
9
Number
Integer
List<Number>
List<Integer>?
![Page 10: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/10.jpg)
WhatareJavarules?• GiventwoconcretetypesAandB,MyClass<A>hasno
rela9onshiptoMyClass<B>,regardlessofwhetherornotAandBarerelated.
• Formally:subtypinginJavaisinvariantforgenericclasses.
• Note:ThecommonparentofMyClass<A>andMyClass<B>isMyClass<?>:the“wildcard”?Willbediscussedlater.
• Ontheotherhand,asexpected,ifAextendsBandtheyaregenericclasses,foreachtypeCwehavethatA<C>extendsB<C>.
• Thus,forexample,ArrayList<Integer>issubtypeofList<Integer>
10
![Page 11: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/11.jpg)
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);
IstheSubs9tu9onPrinciplesaQsfiedineitherdirecQon?ThusList<Number>isneitherasupertypenorasubtypeofList<Integer>:Javarulesareadequatehere 11
Number
Integer
List<Integer> lisInt = new …;!List<Number> lisNum = new …; !lisNum = lisInt; !// ???!lisNum.add(new Number(…));//no!listInt = lisNum; !// ???!Integer n = lisInt.get(0); //no!
![Page 12: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/12.jpg)
ButinmorespecificsituaQons…interface List<T> { T get(int index); }
typeList<Number>: Number get(int index);
typeList<Integer>: Integer get(int index);
Acovariantno9onofsubtypingwouldbesafe:– List<Integer>canbesubtypeofList<Number> – NotinJava
• Ingeneral:covarianceissafeifthetypeisread-only
12
Number
Integer
![Page 13: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/13.jpg)
Viceversa…contravariance!interface List<T> { boolean add(T elt); }
typeList<Number>: boolean add(Number elt);
typeList<Integer>: boolean add(Integer elt);
Acontravariantno9onofsubtypingwouldbesafe:
– List<Number>canbeasubtypeofList<Integer> – ButJava…..
Ingeneral:contravarianceissafeifthetypeiswrite-only
13
Number
Integer
![Page 14: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/14.jpg)
GenericsandsubtypesinC#• InC#,thetypeparameterofagenericclasscanbe
annotatedout(covariant)orin(contravariant),otherwiseitisinvariant.Examples:
• Ienumeratoriscovariant,becausetheonlymethodreturnsanenumerator,whichaccessesthecollecQoninread-only
• IComparableiscontravariant,becausetheonlymethodhasanargumentoftypeT
14
public interface IEnumerable<out T> : […] {!!public […]IEnumerator<out T> GetEnumerator ();!
}!
public interface IComparable<in T> {!!public int CompareTo (T other);!
}!
![Page 15: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/15.jpg)
Co-andContra-varianceinScala
• AlsoScalasupportsco/contra-varianceannotaQons(-and+)fortypeparameters:
!class VendingMachine[+A]{…}!!class GarbageCan[-A]{…}!!trait Function1[-T, +R] extends AnyRef !{ def apply(v1: T): R }!
15
http://blog.kamkor.me/Covariance-And-Contravariance-In-Scala/!
![Page 16: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/16.jpg)
Adigression:Javaarrays
• Arraysarelikebuilt-incontainers– LetType1beasubtypeofType2.– HowareType1[]eType2[]related?
• Considerthefollowinggenericclass,mimickingarrays:class Array<T> {! public T get(int i) { … “op” … }! public T set(T newVal, int i) { … “op” … }!}!AccordingwithJavarules,Array<Type1>andArray<Type2>arenotrelatedbysubtyping
16
![Page 17: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/17.jpg)
Butinstead…
• InJava,ifType1isasubtypeofType2,thenType1[]isasubtypeofType2[].ThusJavaarraysarecovariant.
• Java(andalsoC#,.NET)fixedthisrulebeforetheintroducQonofgenerics.
• Why?Thinkto• Notconvenienttochangeitbecauseofretro-compabilityconsideraQons.
• Covarianceworksfine,providedyoudonotchangethecontentofanarray…
17
void sort(Object[] o);!
![Page 18: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/18.jpg)
Asafeuseofcovarianceinarraysvoid maybeSwap(LibraryHolding[] arr) { if(arr[17].dueDate() < arr[34].dueDate()) // … swap arr[17] and arr[34] } // client Book[] books = …; maybeSwap(books); // uses covariance of arrays
18
LibraryHolding
Book CD
![Page 19: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/19.jpg)
ButinserQoncausesfailure
void replace17(LibraryHolding[] arr, LibraryHolding h) { arr[17] = h; }
// the client Book[] books = …; LibraryHolding theWall = new CD("Pink Floyd", "The Wall", …); replace17(books, theWall); Book b = books[17]; // contains a CD b.getChapters(); // problem!!
19
LibraryHolding
Book CD
![Page 20: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/20.jpg)
Java’schoices• Foreachreferencevariable,thedynamictype(typeoftheobject
referredbyit)mustbeasubtypeofthesta9cone(typeofdeclaraQon).– ViolatedforBook b
• Javadesignchoices:– ThedynamictypeofanarrayisknownatrunQme(Book[],or
beBer[Lmypackage.Book;inJVMtypesyntax)– EveryJavaarray-updateincludesrun-9mecheck– AssigninganobjectofasupertypetoanarraythrowsanArrayStoreException
• Thusreplace17throwsanexcepQon
20
![Page 21: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/21.jpg)
Asimplerexample
21
Apple[] apples = new Apple[1];!Fruit[] fruits = apples;!fruits[0] = new Strawberry();! // JVM throws ArrayStoreException !
![Page 22: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/22.jpg)
Aseriousconsequence• EveryJavaarray-updateincludesrun-Qmecheck,but• GenerictypesarenotpresentatrunQmeduetotypeerasure,thus
• ArraysofgenericsarenotsupportedinJava• InfacttheywouldcausetypeerrorsnotdetectableatrunQme,breakingJavastrongtypesafety
22
List<String>[] lsa = new List<String>[10]; // illegal!Object[] oa = lsa; // OK by covariance of arrays !List<Integer> li = new ArrayList<Integer>();!li.add(new Integer(3));!oa[0] = li; // should throw ArrayStoreExeception, ! !// but JVM only sees “oa[0]:List = li:ArrayList”!String s = lsa[0].get(0); // type error !!!
![Page 23: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/23.jpg)
Wildcardsforcovariance
• InvarianceofgenericclassesisrestricQve• Wildcardscanalleviatetheproblem• Whatisa“generalenough”typeforaddAll?
interface Set<E> { // Adds to this all elements of c // (not already in this) void addAll(??? c); }
• void addAll(Set<E> c) // andList<E>? • void addAll(Collection<E> c)
// andcollecQonsof T <: E? • void addAll(Collection<? extends E> c); // ok 23
![Page 24: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/24.jpg)
Wildcards,forbothco-andcontra-variance
Syntaxofwildcards:– ? extends Type,denotesanunknownsubtypeofType – ?,shorthandfor? extends Object – ? super Type,denotesanunknownsupertypeofType
wildcard=anonymousvariable– ?Unknowntype– Wildcardareusedwhenatypeisusedexactlyonce,andthenameis
unknown– Theyareusedforuse-sitevariance(notdeclara9on-sitevariance)
24
![Page 25: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/25.jpg)
The“PECSprinciple”:ProducerExtends,ConsumerSuper
Whenshouldwildcardsbeused?– Use? extends Twhenyouwanttogetvalues(fromaproducer):supportscovariance
– Use? super Twhenyouwanttoinsertvalues(inaconsumer):supportscontravariance
– Donotuse?(Tisenough)whenyoubothobtainandproducevalues.
Example: <T> void copy(List<? super T> dst, List<? extends T> src);
25
![Page 26: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/26.jpg)
Whatabouttypesafety?
• Arrayscovariance:
• Covariancewithwildcards:
26
Apple[] apples = new Apple[1];!Fruit[] fruits = apples;!fruits[0] = new Strawberry();! // JVM throws ArrayStoreException !
List<Apple> apples = new ArrayList<Apple>();!List<? extends Fruit> fruits = apples;!fruits.add(new Strawberry()); !
!// compile-time error!!!!
![Page 27: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/27.jpg)
Thepricetopaywithwildcards• Awildcardtypeisanonymous/unknown,andalmostnothingcanbedone:
27
List<Apple> apples = new ArrayList<Apple>();!List<? extends Fruit> fruits = apples; //covariance!fruits.add(new Strawberry()); // compile-time error! OK!Fruits f = apples.get(0); // OK!fruits.add(new Apple()); // compile-time error??? !fruits.add(null); //ok, the only thing you can add ! !
List<Fruit> fruits = new ArrayList<Fruits>();!List<? super Apples> apples = fruits; //contravariance!fruits.add(new Apple()); // OK!fruits.add(new FujiApple()); // OK!fruits.add(new Fruit()); // compile-time error, OK!Fruits f = apples.get(0); // compile-time error???!Object o = apples.get(0); //ok, the only way to get!
![Page 28: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/28.jpg)
Typeerasure
AlltypeparametersofgenerictypesaretransformedtoObjectortotheirfirstboundadercompilaQon– MainReason:backwardcompaQbilitywithlegacycode
– Thusatrun-Qme,alltheinstancesofthesamegenerictypehavethesametype
List<String> lst1 = new ArrayList<String>(); List<Integer> lst2 = new ArrayList<Integer>(); lst1.getClass() == lst2.getClass() // true 28
![Page 29: 301AA - Advanced Programming [AP-2017] - unipi.itpages.di.unipi.it/corradini/Didattica/AP-17/SLIDES/AP...301AA - Advanced Programming [AP-2017] Lecturer: Andrea Corradini andrea@di.unipi.it](https://reader031.fdocuments.in/reader031/viewer/2022030417/5aa3225c7f8b9a436d8dd670/html5/thumbnails/29.jpg)
LimitaQonsofJavaGenerics• CannotInstanQateGenericTypeswithPrimiQveTypesArrayList<int> a = … //does not compile• CannotCreateInstancesofTypeParameters• CannotDeclareStaQcFieldsWhoseTypesareTypeParameterspublic class C<T>{ public static T local; …}!• CannotUseCastsorinstanceofWithParameterizedTypes(list instanceof ArrayList<Integer>) // does not compile!(list instanceof ArrayList<?>) // ok• CannotCreateArraysofParameterizedTypes• CannotCreate,Catch,orThrowObjectsofParameterizedTypes• CannotOverloadaMethodWheretheFormalParameterTypesofEach
OverloadErasetotheSameRawTypepublic class Example { // does not copile!public void print(Set<String> strSet) { } !public void print(Set<Integer> intSet) { } }!
29