Post on 16-Jun-2020
transcript
TechnikenderProgrammentwicklung
Prof.Dr.WolfgangSchramm
GENERICS9.Kapitel
1
Übersicht
1. ProgrammstrukturierungmitPaketen(packages)
2. Vererbung3. AbstrakteKlassenundInterfaces4. Ausnahmebehandlung5. Datenströme:dieJavaIO-Bibliothek6. Multithreading7. Collections8. InnereKlassen9. Generics10. Reflection
2
LernzieledesKapitels
¨ Verstehenwarumman(inJava5)Generics eingeführthat.
¨ KennenlernendesGeneric-Konzepts.
¨ Verstehen,wasgenerischseinkann.
¨ SelbstgenerischeKlassenundMethodenschreibenkönnen.
3
Inhalt
1. Einführung/Motivation2. Generics (Definition)3. GenerischeKlassen
• Subtyping• Wildcards
4. GenerischeMethoden5. Anwendungsbeispiele
5
Beispiel:EinfacherStack fürbestimmteObjekte
Stack für Integer-ObjekteStack für String-Objekte
Schlecht: 2 x quasi derselbe Code für dieselben Aufgaben.Frage: Kann man das mit unserem Wissen nicht besser machen?Wenn ja: Wie?
6
Beispiel:EinfacherStack füralleArtenvonObjekten
Laufzeitfehler
7
ADTStack:ProblemTypsicherheit
o DerADTStack istprinzipielloffenfürjedenTyp.o ManspeichertObjektevomallgemeinstenTypObject.o BeimLesenvomStack (pop)werdendieseallgemeinenObjekte
auchwiederzurückgeliefert.o WennmanineinemStack Integer-Objektespeichert,willmandort
keineString-Objektespeichern– dochmiteinenallgemeinenTypObject kanndasnichtverhindertwerden.
o AbhilfeseitJava5:dieNutzungvonGenericsà bessereTypsicherheit,dennnurganzspezielleObjektekommenindieDatenstruktur.
o MitdenGenerics lässtsichbeiderKonstruktiondesADTStackangeben,welcheObjekteindenStack aufgenommenwerdendürfen.
o Dannistmanauchsicher,welcheObjektemanvomStack zurückbekommt.
8
Motivation
o WieabstrahiereichvomkonkretenTypeinesObjekts?o Wiekannich(typsichere)Containerklassen(z.B.einenADT
Stack)bauen,diejedesbeliebigeObjektaufnehmenkönnen?o WiebaueichtypsichereFrameworks?o Wievermeideich(unsichere)Casts undmachedadurch
meinenCodetypsicher?
9
Beispiel:Stack mitGenerics
10
Beispiel:Stack mitGenerics
Compilezeitfehler
11
GenerischeTypen– Warum?
o BeidenerstengetyptenProgrammiersprachen(z.B.Pascal):⇒ ProgrammierermusstedieselbeDatenstrukturfürjeden
Datentyp,derunterstütztwurde,definieren.⇒ EineListevonZahlen,eineListevonZeichenundeineListe
vonDatumsangabenwird(imGrunde)aufdieselbeWeiseprogrammiert.DieAlgorithmenzumEinfügen,SuchenundLöschenlaufenstetsgleichab.
¨ Wünschenswert:dieImplementierungderListeunabhängigvondiesenTypenvorzunehmen.
o ErsterVerbesserungsansatzinJavadurchVererbungsbeziehung⇒ Zielnurteilweiseerreichtà keineUnterstützungbezüglich
derTypüberprüfungenzurCompilezeit.
12
GenerischeTypeninJava
o EingenerischerTypà ErzeugungvonDatentypen,dievondenzuGrundeliegendenTypenabstrahieren.
o CharakteristischfürgenerischenProgrammierungà dieAlgorithmenwerdennichtfüreinenbestimmtenDatentypgeschrieben.SiestellennurbestimmteAnforderungenandieTypen.
o GenerischeTypen inderInformatik:DatentypenmitderMöglichkeitzurAngabevonTypparametern.
13
GenerischeProgrammierung– Wasistdas?
o InC++:Templates,inJava:Generics.o DerBegriffstehtsynonymfür„parametrisierteTypen“.o Idee:EswerdenzusätzlicheVariablenfürTypen,sogenannte
Typ-Variableneingeführt.o DieseTyp-VariablenrepräsentierenzumZeitpunktder
ImplementierungunbekannteTypen.o ErstbeiderVerwendungderKlassen,Schnittstellenund
MethodenwerdendieseTyp-VariablendurchkonkreteTypenersetzt.
o DamitkanntypsichereProgrammierunggewährleistetwerden.
14
Generics – wiefunktionierensie?
Fehlermeldung zur Compilezeit!
Aktueller Typparameter
Kein Cast mehr nötig!
The method push(String) in the type GenericSimpleStack<String> isnot applicable for the arguments (int)
15
Generics:Eigenschaften
o GenerischeTypenerlaubenvomkonkretenTypzuabstrahieren.¤ mitderMöglichkeitzurAngabevonTypparametern,d.h.Typeiner
Variable,einesParameters,einesRückgabewertesetc.istselbereinVariable(typevariable).
¤ KlassenundMethodenhaben,quasialsSchablone,einenzusätzlichenTyp-Parameter(typeparameter),diesesetzendanndieTypvariablen.
¤ DerProgrammierersetztdieTyp-Parameter,sowieeresbrauchtundparametriertdamitdieKlassenbzw.Methoden.
¤ KlassenmitTyp-Parameternà generischeTypen(generic types)bzw.generischeKlassen(generic classes)
¤ MethodenmitTyp-Parameternà generischeMethoden(genericmethods)
Þ TypprüfungbereitszurCompilezeità Typsicherheit.Þ VerbessertLesbarkeitundRobustheitderProgramme.Þ (Entfernte)ÄhnlichkeitenzuTemplatesinC++
15
16
Generics Definition
¨ DefinitionvonTypparametern:inspitzenKlammernhinterdemKlassen-oderInterfacenamen.
¨ TypparameterinnerhalbderKlassebzw.desInterfacesverwendbarwieeinTyp.
¨ Typparameter:keineelementarenDatentypen,nurUnterklassenvonObject zulässig.
¨ EmpfehlungfürNamenskonvention¤ Großbuchstabe¤ EinContainerklassen
Formaler Typparameter
Verwendung des Typparameters bei AttributenVerwendung
des Typ-parameters in Methoden
17
Generics – BegriffeundBeispiele
Name Beispiel
Generischer Typ (generic type) List<E>
Formaler Typ-Parameter (formal type parameter) E
Parametrisierter Typ (parametrized type) List<String>
Aktueller Typ-Parameter (actual type parameter) String
Ungebundener Wildcard-Typ (unbounded wildcard type) List<?>
Raw Type List
Gebundener Typ-Parameter (bounded type parameter) <E extends Number>
Rekursiv gebundener Typ-Parameter (recursive bounded type) <E extends Comparable<E>>
Gebundener Wildcard-Typ (bounded wildcard type) List<? extends Number>
Generische Methode (generic method) static <E> List<E> asList(E[] a)
Type Token String.class
18
Generics – RealisierunginJava
o Generics sindeinCompile-Zeit-Konstrukt,d.h.dieGenericsexistierennurzurCompile-Zeit.
o DieTyp-InformationendesgenerischenTypswerdenvomCompilerentfernt(Typlöschung/typeerasure).¤ Typ-ParameteristzurLaufzeitvomTypObject.¤ Typ-ParameterkannnichtinstatischenVariablenoderMethodenverwendet
werden.¤ Typ-Parameterkannnichtverwendetwerden,umObjektezuerzeugen.
o EsgibtzurLaufzeitnureineeinzige KlasseprogenerischemTyp(Raw type)– sog.homogeneÜbersetzung.
o InC++wirdfürjede AusprägungeinesTemplatesderCodefüreineKlassebzw.Funktiongeneriertundcompiliert;esgibtalsoprogenerischemTypinC++eineKlasse– sog.heterogeneÜbersetzung.
19
Raw-TypeeinergenerischenKlasse
GenerischeKlassemitTypvariablen. VomCompilerausdergenerischenKlassegeneriertersog.Raw-Type.
Compilezeitkonstrukt Laufzeitkonstrukt
20
Typ-VariablenundparametrisierteTypen-Kompatibilität
Gegeben:class C<E> { … }
class A { … }
class B extends A { … }
DanngeltendenfolgendeKompatibilitätsbedingungen:C<A> # C<B> VererbungsbeziehungkannnichtaufgenerischeTypenübertragen
werden.
C<B> # C<A>
C<Object> # C<A>
C<Object> # C<B>
C ¬ C<A> Derraw-TypeistmitjedemgenerischenTypkompatibel
C ¬ C<B>
Object ¬ E
E # Object
Legende:¬ kompatibel# nicht kompatibel
Erklärung: s.u.
21
ParametrisierteTypen:parametrisierterTypalsaktuellerTyp-Parameter
Gegeben:class C<E> { … }
class D<T> { … }
Verwendung der Klasse C:
C<D<A>> c = new C<D<A>>();
oder
C<D<D<D<D<D<A>>>>>> c = new C<D<D<D<D<D<A>>>>>>();
22
ParametrisierteTypen:parametrisierterTypalsaktuellerTyp
Gegeben:class A { … }class B<E> { … }
DefinitionderKlasseC:class C<E> {
B<E> b;void set(B<E> b) { this.b = b; }B<E> get() { return this.b; }
}VerwendungderKlasseC:C<A> c = new C<A> ();c.set(new B<A> ());B<A> b = c.get();
Attribut-Typ ist eine Typ-Variable
Formaler Typparameter
Parametrisierter Typ
23
Typ-VariablenmitEinschränkungen:gebundenderParametertyp
DieTyp-VariableEderKlasseisteingeschränktaufCA-kompatibleTypen.
Vom Compiler generierter Raw-Type.
24
SinnvonEinschränkungen
o EinschränkungvonTypenisteinspezifischerKontrakt:¤ Eswirdgarantiert,dassderaktuelleTyp-ParametereinersolchenKlasse
kompatibelzuderdefiniertenEinschränkungist.¤ ÜbereineReferenzvomTypderTyp-Variablenkönnentypsicherallefür
deneinschränkendenTypdefiniertenMethodenaufgerufenwerden.
Ohne Einschränkung auf CA könnte man auf eine E-Referenz nur die Methoden der Klasse Object aufrufen.
Methode m der Klasse CA kann aufgerufen werden.
25
GenerischeKlassenundVererbung
o GenerischeKlassenkönnenSubklassenhaben.o DieSubklasseist
¤ Entwederselbstwiedergenerisch,oder¤ DieSubklasselegtdenTyp-Parameterfestundistdamitnichtgenerisch.
26
GenerischeKlassenundVererbung– Beispiel„GenerischeSubklasse“
Klasse B ist selbst generisch.
27
Klasse C ist nicht generisch –legt den Typ von A fest (bindet den formalen Parameter E an Double)
GenerischeKlassenundVererbung– Beispiel„Nicht-GenerischeSubklasse“
Mischformen sind möglich !!!
28
Generics undSubtyping?
Fehler?!
Ist eine Liste von Strings auch eine Liste von Objekten?
Versuch einem String ein Objekt zuzuweisen!
... sonst ginge das:
Subtyping nicht erlaubt!!!
29
Invarianz
o Generics sindinvariant¤ DieAbleitungsbeziehungzwischenTypargumentenüberträgtsichnichtauf
generischeKlassenà GenerischeTypenvonSubtypensindselberkeineSubtypen(invarianteTypen,keineKovarianz).
¤ EsgibtdaherauchkeinePolymorphiezwischenverschiedenenAusprägungendesselbengenerischenTyps.
30
TypsichereBehandlungvonverschiedenen(generischen)Collections
Beispiel ohne Generics
Naheliegender Ansatz mit Generics
for-each-Schleife
Nur Collections, die mit Objectparametrisiert sind, können an die Methode übergeben werden!Kein Subtyping bei Generics !!!
Hoffnung:• durch die Definition des Methodenparameters als Collection<Object> wird auch Collection<String> akzeptiert.
Realität:• Das ist aber nicht so.• Beide Typen stehen in keinerlei Beziehung zueinander.• Sie sind zwar durch Parameterisierung aus demselben generischen Typ entstanden, aber sie sind in keiner
Weise kompatibel zueinander.
Generics sind invariant
31
Wildcards
o Wildcards<?>à bewusstes„Vergessen“derTypinformationenbzw.zeigenan,dassjedebeliebigeAusprägungeinesgenerischenTyps(=“alleReferenztypen“)möglichist.
o <?> stehtfürunbekannterTypnichtfürObjekt(sonstgältenjadieEinschränkungenvonoben).
o <?>istdieKurzform von<?extends Object>o DamitistesmöglichverschiedeneUnterklassenzusammenzuführen.o Bound Wildcards<?extends E>bzw.<?superE>stellensicher,dassnicht
jedebeliebigeAusprägungdesgenerischenTypssondernnurbestimmtemöglichsind.
o VerwendungvonWildcards:¤ NurbeiderDeklaration vonParameternundVariablen.¤ BeiderObjekterzeugung undderDeklarationvongenerischenTypenkönnensienicht
verwendet werden.EsgibtalsokeineObjekteeinesWildcard-Typs.
32
Wildcards:Beispiel1
Der parame-trisierteTyp Typ von bo2 ist unbekannt.
Der parame-trisierteTyp von bo1 ist Number.
Box <?> bo3 = new Box <?>();
Bei der Erzeugung muss der aktuelle Typparameter angegeben werden, er darf nicht unbekannt bleiben.
33
Wildcards:Beispiel2
• Neuer Ansatz mit Generics
„Collection of unknown“ Wildcard
Akzeptiert alle Arten von Collections!
34
Gebundene/Upper Bound Wildcards
Lösung à später
Nur Subtypen von Number sind als unbekannter generischer Typ zulässig!
Die Nutzung der Box<Number> ist eingeschränkt: setValue() funktioniert nur über die konkrete Box<Integer> (also bI), aber nicht über die allgemeine Box<Number>.Der Zugriff ist unproblematisch.
Auf einem Typ, der mit einem nach oben beschränkten Wildcard parametrisiert ist, dürfen keine Methoden aufgerufen werden, die den Typparameter als Methodenparameter haben.
35
GebundeneWildcardsbeiParametern
Wildcard für alle Klassen die Unterklasse von Shape sind
36
Gebundene/Lower Bound Wildcards
Nur Supertypen von A1 sind als unbekannter generischer Typ zulässig!
37
Mischenvonupper undlower bound Wildcards
Mit der upper bound Wildcard (dem maximalen Typ) funktioniert das Lesen der Daten, aber nicht das Hinzufügen.Lesen von Daten aus generischem Typ è upper boundWildcards
Mit der lower bound Wildcard (dem minimalen Typ) funktioniert nun das Hinzufügen – aber nicht mehr das Lesen der Daten.Hinzufügen von Objekten zu generischem Typ è lowerbound Wildcards
Nur Supertypen von Number sind als unbekannter generischer Typ zulässig!
38
Verwendungvonupper- undlower-bounds
o Lesen vonDatenausgenerischemTypè upper boundWildcards:
<?extends T>à Tistdermaximale Typo Hinzufügen vonObjektenzugenerischemTypè lower
bound Wildcards<?SuperT>à Tistderminmale Typ
39
ZusammenfassendesBeispiel
40
GenerischeMethoden
EineKlassekannganznormalohneGenerics deklariertwerden,abermitMethoden,diedieTypengenerischvorschreiben.o SowohlKlassenmethodenalsauchObjektmethodenkönnenals
generischeMethodendeklariertwerden,z.B.static <E> Stack<E> combine (Stack<E> p).
o ImGegensatzzuKlassenmussderVerwenderdenTyp-Parameternichtexplizitsetzen,derCompilerleitetihnausdenTypendesAufrufsab(typeinference).
o InseltenenFällenmussmandenTypfürdieMethodeexplizitangeben.o InteressantistdiesfürUtility-Klassen,dienurstatischeFunktionen
anbieten,aberselbstnichtalsObjektvorliegen.
Angabe von <E> beimKlassennamen entfälltund verschiebt sichauf die Deklaration derMethode.
Rückgabetyp: Objektder generischenKlasse Stack<E>
Parametertyp: Objektder generischenKlasse Stack<E>
41
GenerischeMethoden:Beispiel1
class MyStack<E> implements Stack<E>
2 Integer Stacks werden zu einem Stack zusammengefasst.
42
GenerischeMethoden:Beispiel2
Fehler zur Compilezeit!
Typparameter Verwendung des Typparameters
43
GenerischeMethodenmitgebundenenParametern
o Typ-Parameterkönnen- analogzuWildcards– aufbestimmteKlassenbeschränktwerden.
o <Textends C>- schränktTaufCundSubklassenvonCein.o <TsuperC>- schränktTaufCundSuperklassenvonCein.
44
GenerischeMethoden:Beispiel3
T muss von Klasse A abgeleitet sein
T muss von Klasse A und den Interfaces I1 und I2 abgeleitet sein
T muss von den Interfaces I1 und I2 abgeleitet sein
45
Generics mitmehrerenTypparametern
46
Generics undArrays
o Generics undArraysunterscheidensichgrundsätzlichundharmonierenimallgemeinenschlecht.
o Arrayssindkovariant (covariant)o Generics sindinvariant (invariant)o ArraysprüfenihrenTypzurLaufzeit(reified)o Generics sindeinCompilezeitkonstrukt,prüfenihrenTyp
deshalbzurCompilezeit (typeerasure).o DieTyplöschungistderGrunddafür,dasArraysnichtso
umgesetztwerdenkönnen,wiemanessichnaivvorstellt.o EsistnichtmöglicheinArrayzuerstellenaus
¤ einemgenerischenTyp(List<E>[])¤ einemparametriertenTyp(List<String>[])¤ einemTyp-Parameter(E[])
47
Kovarianz,Kontravarianz,Invarianz
Vererbung vom Typ des Methodenparameters bzw. Rückgabewerts
Typhierachie des Methodenparameters bleibt unverändert
Typhierarchie des Rückgabewertes der Methode ist mit der Vererbungshierarchie von ClassA und ClassB
Typhierarchie des Methodenparameters ist entgegen der Vererbungshierarchie von ClassA und ClassB
Quelle: Wikipedia
48
Runtime-Klassen
o WasgibtdasfolgendeProgrammaus?
Gibt „true“ aus, weil alle Instanzen einer generischen Klasse dieselbe Runtime-Klasse haben
49
Anwendungsbeispiel:Queue
50
Anwendungsbeispiel:List
51
Anwendungsbeispiel:Node
52
EinsatzvonGenerics
o Allgemein¤ Generics sindeineFormvonPolymorphie.¤ Dieseistimmerdannsinnvoll,wennderCodewiederverwendbarsein
soll.
o Generics kontraPolymorphiedurchSubtyping:¤ Generics fürdieTypsicherheit.¤ VorteilgegenüberCasts durchfrühereFehlererkennung.
o DerEntwicklerwirdnichtgezwungenGenerics zuverwenden.o Eineunchecked Warnungweistdaraufhin,dassdie
Typsicherheitnichtgewährleistetist.
53
Zusammenfassung
o Generics erlaubentypsicherzuprogrammieren¤ TypprüfungenerfolgenbereitszurCompilezeit nichterstzurLaufzeit.
D.h.FehlertretenandenStellenauf,wosieverursachtwerden.¤ Generics helfendabeiProgrammerobusterundwenigerfehleranfällig
zumachen.n DasWegfallenvonCasts machtdenCodeübersichtlicher.n Bedingungenlassensichbesserundeinfacherausdrücken.
o GenerischeKlassenkönnenleichtwiederverwendetwerden.
o InBezugaufArraysistdasKonzeptnochnichtausgereift.
54
Generics – ErweiterungeninJava7
MitJava7istdieTyp-InferenzfürGenerics deutlichverbessertworden:o IndenmeistenSituationenmussmandenTyp-Parameternur
nochbeiderDeklarationsetzen.o BeiderObjekterzeugungkanndieAngabedesTyp-
Parametersdurchdendiamond <>ersetztwerden.
Beispiele:List<String> list = new ArrayList<>();
Map<Integer, String> map = new HashMap<>();
Set<?> set = new HashSet<>();
55
WeitereInfoszuGenerics
o http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdfo http://angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.pdf