GENERICS 9. Kapitel -...

Post on 16-Jun-2020

6 views 0 download

Transcript of GENERICS 9. Kapitel -...

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