34
Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik I Thema 18: Typkonvertierungen und Generiz Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Grundlagen der Informatik I Thema 18: Typkonvertierungen und Generizität

  • Upload
    abeni

  • View
    40

  • Download
    0

Embed Size (px)

DESCRIPTION

Grundlagen der Informatik I Thema 18: Typkonvertierungen und Generizität. Prof. Dr. Max Mühlhäuser Dr. Guido Rößling. Typkonvertierung. Mit statischer Typisierung gibt es viele Kontexte, in denen Werte eines bestimmten Typs erwartet werden. - PowerPoint PPT Presentation

Citation preview

Page 1: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Telecooperation/RBG

Technische Universität Darmstadt

Copyrighted material; for TUD student use only

Grundlagen der Informatik IThema 18: Typkonvertierungen und Generizität

Prof. Dr. Max MühlhäuserDr. Guido Rößling

Page 2: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Typkonvertierung

• Mit statischer Typisierung gibt es viele Kontexte, in denen Werte eines bestimmten Typs erwartet werden.– In “a = expression” erwarten wir, dass expression den

gleichen Typ wie a hat– In “a + b” erwarten wir, dass a und b entweder beide

ganze Zahlen, Fließkommazahlen oder Zeichenketten sind.

– In “f(a,b)” erwarten wir, dass die Typen der Argumente sich mit denen der formalen Parameter decken.

2

Page 3: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Arten der Typkonvertierung in Java

• Identitätskonvertierung – von einem Typ auf denselben Typ– Es ist z.B. ok, eine redundante Konvertierung

einzufügen

• Verbreiterung primitiver Typen– z.B. byte nach int (ohne Informationsverlust)– z.B. int nach double (möglicher Informationsverlust)

• Verengung primitiver Typen– z.B. int nach byte (höhere Bits wegwerfen)– z.B. float nach int

3

Page 4: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Arten der Typkonvertierung in Java• Verbreiterung von Referenztypen

(Verallgemeinerung)– Gegeben Referenztypen A, B, dann kann A zu B verbreitert

werden genau dann wenn A ein Subtyp von B ist.

– Diese Konvertierung geschieht immer während der Kompilierung und kann keine Laufzeitfehler auslösen.

• Verengung von Referenztypen (Konkretisierung)– Gegeben Referenztypen A, B, dann kann A verengt werden zu B

genau dann wenn B ein Subtyp von A ist.

– Diese Konvertierung muss zur Laufzeit überprüft werden und löst möglicherweise einen Laufzeitfehler aus.

4

Page 5: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Arten der Typkonvertierung in Java• String Konvertierung

– Jeder Typ kann zu String konvertiert werden– Implizit wird die toString()-Methode (aus java.lang.Object)

benutzt– Das haben Sie z.B. bei System.out.println(myObject) schon

genutzt• Boxing und Unboxing

– Von byte zu Byte, int zu Integer etc. und umgekehrt

• Ungeprüfte Konvertierung– Konvertierungen die zu einem Fehler führen können, ergeben

Warnung zur Kompilierzeit

– z.B. Konvertierung eines “raw type” zu einem parametrisierten Typ

5

Page 6: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Konvertierungskontexte• Zuweisungskonvertierung: v = expr

– Konvertiere den Typ von expr zum Typ von v. – Nur für Konvertierungen ohne mögliche Laufzeitfehler

• Methodenaufrufkonvertierung: expr.M(expr‘)– konvertiert die Typen der Argumente. – Nur für Konvertierungen ohne mögliche Laufzeitfehler

• Cast-Konvertierung: (T)expr – Konvertiert den Typ von expr zu T– Kann auch die Verengungskonvertierung benutzen!

• Numerische Konvertierung– Konvertiert die Operanden eines numerischen Operators in

einen gemeinsamen Typen, so dass die Operation ausgeführt werden kann

• erlaubt Identitäts-, Verbreiterungs- und Unboxing Konvertierung

• 4 + 2.0 6.06

Page 7: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Typ-Verengung• Verbreiterung verliert statische Typinformation

// p bezieht sich auf Circle, Verbreiterung OKGraphicObject p = new Circle(5, 12, 4); Circle c1 = p; // compile-Fehler — kann nicht verengen

• Die Information kann zur Laufzeit mit Tests und Casts wieder zurückgeholt werden kann

if (p instanceof Circle) { // Laufzeittest c1 = (Circle) p; // Explizite Verengung

} // zur Laufzeit OK

7

Page 8: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Nochmals Collections…• Eine Collection sollte zu mehr als einem Typ

passen– Eine Implementierung langt für verschiedene Zwecke– Das allgemeine Verhalten der Collection hängt nicht vom

Elementtyp ab• Zusätzlich wollen wir einen spezifischen

Elementtyp garantiert haben– Angenommen, wir nutzen eine Collection nur für Person

Instanzen– Dann wollen wir auch Person Objekte ohne Verendung

von Object erhalten können!

8

Page 9: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Nochmals Collections…List myIntList = new LinkedList(); // 1myIntList.add(new Integer(0)); // 2Integer x = (Integer)myIntList.get(0); // 3• Der Cast in Zeile ist nervig aber erforderlich

– Java garantiert nur, dass das Ergebnis zum Typ Object passt– Es kann also vom Typ Integer sein – oder eben auch nicht!

• Daher kriegen wir einen Typfehler ohne den Cast• Zudem wurde der Cast nicht mit instanceof

abgesichert • Wir könnten uns auch irren und etwas anderes

erhaltenList myIntList = new LinkedList(); // 1myIntList.add("Hello World"); // 2’Integer x = (Integer)myIntList.get(0); // 3

– Nun erhalten wir eine ClassCastException zur Laufzeit! 9

Page 10: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Angabe der Absichten mit Generics• Wir müssen Java mehr über unsere Absichten

sagen– “Diese Liste will nur Elemente haben, die zu Integer

passen”• Dafür müssen wir…:

– Die Deklaration der Liste anpassen: List<Integer>– Das Anlegen der Liste anpassen: new

LinkedList<Integer>• Vorteile:

– Wir können auf den Cast in Zeile 3 verzichten– Typen, die nicht zu Integer passen, können nicht

eingefügt oder abgefragt werdenList<Integer> myIntList = new LinkedList<Integer>(); // 1myIntList.add(new Integer(0)); // 2Integer x = myIntList.get(0); // 3myIntList.add("Hello World"); // compile-Fehler

10

Page 11: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Was hat sich geändert?• myIntList ist nun eine List<Integer>

– Nicht „eine“ Liste, sondern eine Liste von Integer-Objekten

– Wir müssen Ergebnisse also nicht mehr nach Integer casten

• Wir können keine anderen Typen mehr speichern

• Darum kümmern sich der Java Compiler (und Eclipse)

11

myIntList.add("Hello World");The method add(Integer) in the type List<Integer> is not applicable for the arguments (String)

Page 12: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Und was bringt uns das?• Auf den ersten Blick vielleicht nicht viel

– Die Deklaration und Erzeugung der Liste sind länger– Wir können nur auf den Cast verzichten

• Es gibt aber einen großen Unterschied!– Nun kann der Compiler die Typkorrektheit überprüfen– Die Deklaration von myIntList gibt den Typ an– Der Compiler stellt sicher, dass alle Zugriffe zum Typ

passen• Was ist hier anders als bei einem Cast?

– Mit einem Cast sagt der Programmierer “der Typ sollte hier zum Cast zu Typ X passen”

• Das sollte immer mit instanceof abgesichert werden!– Generische Deklaration sagt “das passt immer zu Typ X“

12

Page 13: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Nochmals ListenList und Iterator werden in java.util wie folgt

definiert:

13

public interface List<E> { void add(E x); Iterator<E> iterator();}public interface Iterator<E> { E next(); boolean hasNext(); void remove();}

• Das kennen wir im Wesentlichen schon (siehe T15)• Außer dem <E> und E

• Damit wird ein formaler Typparameter deklariert• E kann dann in der Klasse als Typ genutzt werden

Page 14: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

List<Integer> und IntegerList• Wir nutzen List<Integer>, aber es gibt nur

List<E>?• E ist ein formaler Typparameter

– Ähnlich zu den formalen Parametern in Methodensignaturen

• E wird in allen Aufrufen durch Integer ersetzt• Intuitiv kann man sich das so vorstellen:

14

public interface IntegerList { void add(Integer x); IntegerIterator iterator();}• Das kann das Verständnis erleichtern

• Aber es ist auch irreführend• Es gibt nur eine List Klasse, nicht “eine pro

Typ”

Page 15: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Generics und Subtypen• Warum ist der folgende Code nicht korrekt?

• Zeile 1 ist sicherlich korrekt– LinkedList ist ein Untertyp von List– Die formalen Parameter (beide String) „passen“

• Passt List<String> in Zeile 2 zu List<Object>?– List ist auf beiden Seiten die gleiche Basisklasse– String ist ein Erbe von Object– Die intuitive Antwort ist also „ja”

15

List<String> ls = new LinkedList<String>(); // 1List<Object> lo = ls; // 2lo.add(new Object()); // 3String s = ls.get(0); // 4

Dieser Code wird vom Übersetzer so nicht akzeptiert!

Page 16: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Generics und Subtypen• Zunächst schauen wir uns den weiteren Code

an:

16

List<String> ls = new LinkedList<String>(); // 1List<Object> lo = ls; // 2lo.add(new Object()); // 3String s = ls.get(0); // 4

• Zeile 2 legt ein Alias der Object und String List an• Wir können ein Object in List<Object> einfügen

(Zeile 3)• Aber wir fügen es gleichzeitig auch in ls ein!

• ls ist deklariert als List<String>…• Aber ls würde nun auch andere Objekttypen enthalten

• Der Compiler erkennt das nicht, wenn Zeile 2 korrekt ist

• Daher wird der Compiler Line 2 zurückweisen“type mismatch: cannot convert from List<String> to

List<Object>”

Dieser Code wird vom Übersetzer

so nicht akzeptiert!

Page 17: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Generics, Subtypen und unsere Intuition

• Sei Y eine Unterklasse von (Klasse oder Interface) X• G sei eine generische Typdeklaration (z.B. List<E>)• G<Y> ist kein Subtyp von G<X>• Warum fällt uns das so schwer zu glauben?• Wir unterstellen, dass sich die Collection nicht

ändert– Das ist natürlich oft eine falsche Annahme!

• Angenommen, das Studierendensekretariat gibt eine Liste der Studenten an das Einwohnermeldeamt– Ein Student ist eine Person– Übergabe von List<Student> für List<Person> wirkt OK– Aber nur, wenn eine Kopie übergeben wird, keine

Referenz!– Das Einwohnermeldeamt fügt eine Person (aber nicht

Student) ein• Die gemeinsame (!) Studentenliste ist nun korrumpiert

17

Page 18: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Generics, Subtypen und Intuition

18

Collection<Vehicle>

Set<Vehicle>

Collection<Car>

Set<Car>

Kovariante Subtypen

PunktweiseSubtypen,

sicher

nicht sicher

Page 19: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Behandlung von Subtypen: Wildcards• Wir wollen alle Elemente einer Collection

ausgeben• Ohne Generics funktioniert das in etwa wie folgt:

• Jetzt passen wir das eben schnell an Generics an:

• Aber diese Methode akzeptiert nur Collection<Object>– Sie akzeptiert keine List<Person>, sondern nur

List<Object>– Zur Erinnerung: List<Person> ist kein Subtyp von

List<Object>

19

void printCollection(Collection c) { for (Object element: c) System.out.println(element);}

void printCollection(Collection<Object> c) { for (Object element: c) System.out.println(element);}

Page 20: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Behandlung von Subtypen: Wildcards• Was müssen wir nun tun?

– Wir brauchen einen gemeinsamen Obertyp für alle Collection-Arten

– Das ist die “Collection von unbekannten Elementtypen”– In Java-Notation: Collection<?> (hier: List<?>)

• Nun können wir den Code anpassen:

• Die Elemente der Liste werden wie Object behandelt– Da java.lang.Object die Superklasse aller Typen ist– Daher passt jeder Typ – auch der „unbekannte Typ ?“ - zu

Object20

void printCollection(Collection<?> c) { for (Object element: c) System.out.println(element);}

Page 21: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

The unbekannte Typ „<?>“• Der „Unbekannte Typ“ <?> wirkt sehr hilfreich

– Wir können endlich auf die Elemente zugreifen!– Falls nötig, können wir sie auf einen konkreten Typ

casten• Natürlich nur wenn der Cast gültig ist!

• Wie steht es mit dem folgenden Code?

• c hat den “unbekannten” Elementtyp “?”• Der einzufügende Typ muss zu “?” passen

– Der Compiler kennt den tatsächlichen Typ von “?” nicht

– Daher ist unklar, ob Object dazu passt– Man darf kein Object einfügen in eine List<String>!– Es kann nur der Wert null eingefügt werden 21

Collection<?> c = new ArrayList<String>();c.add(new Object()); Dieser Code wird

vom Übersetzer so nicht akzeptiert!

Page 22: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Eine generische Zeichenanwendung• Wir betrachten folgendes Modell für ein

Zeichentool:

22

abstract class Shape { abstract void draw(Canvas c); } class Circle extends Shape { private int x, y, radius; void draw(Canvas c) { // ... } } class Rectangle extends Shape { private int x, y, width, height; void draw(Canvas c) { // ... } } class Canvas { void draw(Shape s) { s.draw(this); } }

Page 23: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Eine generische Zeichenanwendung• Jede Form erweitert Shape und kann sich zeichnen• Wir werden meist mehr als eine Form zeichnen!• Also speichern wir die Elemente in einer

List<Shapes>• Wir passen den Code von Canvas entsprechend

an:

• Das funktioniert gut für jede List<Shape>• Und wenn wir eine List<Circle> zeichnen wollen?

– Circle ist ein Subtyp von Shape– Aber List<Circle> ist kein Subtyp von List<Shape>– Der Aufruf drawAll(List<Circle>) führt zu einem Compile-

Fehler23

void drawAll(List<Shape> shapes) { for (Shape s: shapes) { s.draw(this); } }

Page 24: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Eine generische Zeichenanwendung• drawAll passt an sich zu allen Shape-Subtypen• drawAll sollte mit List<Circle>, List<Shape>,

List<Rectangle>, funktionieren…!• Der Einsatz von “?” bringt uns nicht weiter

– Der unbekannte Typ ? hat keine Methode “draw(Canvas)”– Der Cast nach Shape ist möglich aber gefährlich

• Wir müssen die Wildcard beschränken (“bound”)– Sie sollte alle Listen von Subtypen von Shape akzeptieren

• In Java-Notation:

24

void drawAll(List<? extends Shape> shapes) { for (Shape s: shapes) { s.draw(this); } }

Page 25: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Beschränkte Wildcards• Es gibt einen kleinen aber wichtigen Unterschied

– List<Shape> akzeptiert nur genau List<Shape>– List<? extends Shape> akzeptiert Listen von allen

Subtypen von Shape, inklusive Shape selbst• List<Shape>• List<Circle>• List<Rectangle>• …

• “? extends X” bedeutet:– Wir kennen den exakten Type nicht ( “?”)– Aber wir wissen, dass der Typ zu X konform sein muss– X ist die „obere Schranke“ der Wildcard

25

Page 26: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Beschränkte Wildcards• Warum stimmt am folgenden Code nicht?

• Wir können kein Rechteck in List<? extends Shape> einfügen– Wir kennen den exakten Typ der Elemente in shapes nicht– Wir wissen zwar, dass es ein Subtyp von Shape ist– Aber der Typ passt nicht unbedingt zu Rectangle

• Der Aufruf könnte lauten addRectangle(List<Circle>);• Bei unbekanntem Typ können wir nur null einfügen

– Einerseits schlecht…– Dafür gibt es keine Typprobleme zur Laufzeit!– Java geht hier den (typ-)sicheren Weg.

26

void addRectangle(List<? extends Shape> shapes) { shapes.add(0, new Rectangle()); }

Dieser Code wird vom Übersetzer so nicht akzeptiert!

Page 27: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Schreiben von generischen Methoden• Wie kopiert man alle Arrayelemente in eine

Collection?

• Wir können nicht Collection<Object> als Parameter nutzen

• Aber Collection<?> wird auch nicht funktionieren!– Der Typ ist unbekannt, also passt jeder konkrete Typ

potentiell nicht

27

static void copyToCollection(Object[] array, Collection<?> c) { for (Object o: array) { c.add(o); }}

Dieser Code wird vom Übersetzer so nicht akzeptiert!

Page 28: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Schreiben von generischen Methoden• Dazu schreiben wir eine generische Methode:

• Das <T> besagt, dass dies eine generische Methode ist– T wird vor dem Rückgabewert eingeführt

• T dient als formaler Parametertyp• Der Java Compiler nutzt das für Zugangskontrolle

– Der Typ des Feldes und der Collection müssen konform sein

– Es gilt der allgemeinste konforme Typ• Meist langt die Nutzung von Wildcards

– Wildcards werden bevorzugt – klarer und knapper 28

static <T> void copyToCollection(T[] array, Collection<T> c) { for (T o: array) { c.add(o); } }

Page 29: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Abfrage des Typs• Abfrage des Basistyps eines generischen Typs:

• Aber wir erhalten nicht den genauen generischen Typ

– Es gibt nur eine Klasse List (siehe Folie 15)– Die compile-Zeit Information über den formalen

Parameter ist zur Laufzeit nicht verfügbar• Wir können auch getClass() nutzen:

• Die Ausgabe ist wieder true – getClass() liefert java.util.List

29

List<Circle> circles = new ArrayList<Circle>();List<Rectangle> rects = new ArrayList<Rectangle>();System.out.println(circles instanceof List); // true

System.out.println(circles.getClass() == rects.getClass());

System.out.println(circles instanceof List<Circle>); // Fehler

Page 30: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Untere Schranken• Wir wollen eine Datensenke implementieren

– Diese leert eine Collection und gibt das letzte Element zurück

• Was ist hier das generische Typargument <T>?– Es gibt keinen gültigen Typ <T>, da die Typen nicht konform sind– Der Aufruf in der letzten Zeile ist damit illegal

30

interface Sink<T> { void flush(T t);}static <T> T flushAll(Collection<T> c, Sink <T> sink) { T last = null; for (T t: c) { last = t; sink.flush(last); } return last;}Sink<Object> sink;Collection<String> collection;String lastString = flushAll(collection, sink);

Dieser Code wird vom Übersetzer so nicht akzeptiert!

Page 31: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Untere Schranken• Das scheint einfach zu beheben zu sein…:

• Jetzt funktioniert der Aufruf!• Aber: T wird nun auf Object abgebildet

– Weil das der Elementtyp des Sinks ist– Daher scheitert die Zuweisung des Ergebnisses an String

• Wir benötigen “unbekannt, aber Oberklasse von T”• In Java-Notation: <? super T>

31

static <T> T flushAll(Collection<? extends T> c,Sink<T> sink) {

static <T> T flushAll(Collection<T> c,Sink<? super T> sink) {

Page 32: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Implementierungsbeispiel

32

interface Sink<T> { void flush(T t);}class ConcreteSink<T> implements Sink<T> { public void flush(T t) { System.err.println("Flushing " + t + ", type: " +t.getClass().getName()); }} static <T> T flushAll(Collection<T> c, Sink <? super T> sink) { T last = null; for (T t: c) { last = t; sink.flush(last); } return last; } Sink<Object> sink = new ConcreteSink<Object>(); Collection<String> cs = Arrays.asList("a","bb2","cdf"); System.err.println(flushAll(cs, sink));

Bitte denken Sie sich den jeweiligen Klassenkontext dazu!

Page 33: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Statische Typisierung - Zusammenfassung

• Statische Typsysteme sind Gegenstand sehr aktiver Forschung

• Java-ähnliche Typsysteme sind begrenzt, aber im Allgemeinen können Typsysteme sehr mächtig und ausdrucksstark sein– Aber auch sehr kompliziert

• Manche Programmierer sehen statische Typsysteme als eine Begrenzung ihrer Freiheit ("ich weiß, was ich tue")

• Andere Programmierer denken, dass statische Typsysteme nicht nur viele Fehler erkennen, sondern auch eine gute Struktur im Code erzwingen ("erst denken, dann schreiben")

• Die Diskussion ist noch nicht beendet.• Sie sollten eine fundierte Meinung darüber haben!

33

Page 34: Grundlagen der Informatik I Thema 18: Typkonvertierungen  und  Generizität

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T18

Weiterführende Literatur• Die folgenden Materialien bieten (viel) mehr zu

Generics:– Java Tutorial on Generics (by Gilad Bracha):

http://java.sun.com/docs/books/tutorial/extra/generics/– Gilad Bracha, “Generics in the Java Programming Language”

• Diente als Hauptvorlage für diese Folien• http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

– Maurice Naftalin, Philip Wadler: “Java Generics and Collections”, O’Reilly, 2006

34