Generizitt in Java und C Riad Djemili djemiliinf

  • Slides: 57
Download presentation
Generizität in Java und C# Riad Djemili (djemili@inf. fu-berlin. de) Seminar Objektorientierte Programmiersprachen Prof.

Generizität in Java und C# Riad Djemili (djemili@inf. fu-berlin. de) Seminar Objektorientierte Programmiersprachen Prof. Dr. -Ing. Klaus-Peter Löhr FU-Berlin WS 03/04

Übersicht 1. Motivation Polymorphie 2. Probleme 1. 2. Generizität Grundlagen (Eiffel, C++) 2. Java

Übersicht 1. Motivation Polymorphie 2. Probleme 1. 2. Generizität Grundlagen (Eiffel, C++) 2. Java 3. C# 1.

Motivation

Motivation

Polymorphie n Polymorphie Eigenschaft von Variablen, Objekte unterschiedlichen Typs speichern zu können. Variablen können

Polymorphie n Polymorphie Eigenschaft von Variablen, Objekte unterschiedlichen Typs speichern zu können. Variablen können Objekte zugewiesen werden, die vom gleichen Typen wie diese Variable oder von einem abgeleiteten Typen sind. List list = new Linked. List(); ¨ Statischer Typ ¨ Dynamischer Typ In der Variablendeklaration festgelegter Datentyp. Beim Erzeugen des Objekts festgelegter Typ.

Probleme n n n Mächtiges Paradigma, aber nicht perfekt! Statischer Datentyp ist fest und

Probleme n n n Mächtiges Paradigma, aber nicht perfekt! Statischer Datentyp ist fest und kann für eigene Anwendungen nicht leicht angepasst werden. Klassische Lösung: ¨ Nutzung des niedrigsten gemeinsamen Typen der Klassenhiarchie. ¨ Spezialiserte Implementationen mit unterschiedlichen Typen.

Ansatz 1: Nutzung von Vaterobjekten n Beispiel Java: Liste • class My. List {

Ansatz 1: Nutzung von Vaterobjekten n Beispiel Java: Liste • class My. List { boolean add(Object o) {. . } Object get(int index) {. . } } Unsichere Konvention, statt expliziter Sprachunterstützung. • Typwandlungs. Laufzeitfehler, statt Übersetzungsfehler. • Teure Typwandlungen zu Basisklasse und zurück. • Nicht alle Programmiersprachen kennen gemeinsame Vaterobjekte. . . n //associates Integer-Objects My. List ints = new My. List(); ints. add(new Integer(4)); Integer foo = (String)ints. get(0);

Ansatz 2: Spezialisierte Implementationen n Beispiel Java: Math-Methoden public static double abs(double a) {.

Ansatz 2: Spezialisierte Implementationen n Beispiel Java: Math-Methoden public static double abs(double a) {. . } public static float abs(float a) {. . } public static int abs(int a) {. . } public static long abs(long a) {. . } n Methodenüberladen (gleiche Methodennamen mit unterschiedlichen Signaturen), um verschiedene Datentypen zu unterstützen. ¨ Effizient, aber aufgeblähter und unübersichtlicher Code!

Lösung: Generizität (I) Polymorphie Universelle Polymorphie Inklusions. Polymorphie (überschreiben) n Ad hoc – Polymorphie

Lösung: Generizität (I) Polymorphie Universelle Polymorphie Inklusions. Polymorphie (überschreiben) n Ad hoc – Polymorphie (überladen) Parametrische Polymorphie (Generizität) Möglichkeit nicht nur dynamischen Typ, sondern auch statischen Typ zu variieren.

Lösung: Generizität (II) n Ziele ¨ Höhere Typsicherheit, durch Vermeidung von unsicheren Typumwandlungs-Laufzeitfehlern. ¨

Lösung: Generizität (II) n Ziele ¨ Höhere Typsicherheit, durch Vermeidung von unsicheren Typumwandlungs-Laufzeitfehlern. ¨ Wiederverwendbarer Code. ¨ Bessere Lesbarkeit, durch expliziter Syntax, statt impliziter Konvention. ¨ Effizienz, da keine unnötigen Typwandlungen.

Klassische Generizität in Eiffel und C++

Klassische Generizität in Eiffel und C++

Klassen Generizität • Klassen werden mit formalen Typparametern deklariert. • Tatsächliche Datentypen werden als

Klassen Generizität • Klassen werden mit formalen Typparametern deklariert. • Tatsächliche Datentypen werden als Parameter übergeben. Ungenerischer Stack in Eiffel Generischer Stack in Eiffel n class STACK . . feature push ( elem: INTEGER ) is do. . end top: INTEGER is do. . end n class STACK [T] . . feature push ( elem: T ) is do. . end top: T is do. . end n Anwendung: intstack : STACK; intstack. push(3); intstack : STACK[INTEGER]; intstack. push(3);

Mehrere Parametertypen n Ausserdem mehrere generische Parametertypen möglich. ¨ Beispiel: Ein generisches Paar in

Mehrere Parametertypen n Ausserdem mehrere generische Parametertypen möglich. ¨ Beispiel: Ein generisches Paar in Eiffel class PAIR[T, U] feature {NONE} // private first : T; second : U; end ¨ Anwendung: birthdate : PAIR[STRING, DATE];

Methoden Generizität n Generische Typen existieren auch für Funktionen! ¨ Beispiel: Vertausche-Operation in C++

Methoden Generizität n Generische Typen existieren auch für Funktionen! ¨ Beispiel: Vertausche-Operation in C++ template<class T> void swap(T& x, T& y) { T temp = x; x = y; y = temp; } ¨ Anwendung int i, j; swap<int> (i, j); //a swap for int char i, j; swap<char>(i, j); //a swap for char

Methoden Generizität (II) n Im Gegensatz zu generischen Klassen können Typparameter bei Methoden implizit

Methoden Generizität (II) n Im Gegensatz zu generischen Klassen können Typparameter bei Methoden implizit aus Argumenten abgeleitet werden! Beispiel in C++: int i, j; swap(i, j); // a swap for int float i, j; swap(i, j); // a swap for float Ohne explizite Datentypangabe.

Eingeschränkte Generizität n Typeinschränkungen mittels klassischer Polymorphie: bool pos(Comparable foo) {return foo. compare. To(x);

Eingeschränkte Generizität n Typeinschränkungen mittels klassischer Polymorphie: bool pos(Comparable foo) {return foo. compare. To(x); } n Problem: Wie können wir ähnlich sichere Annahmen für generische Typen machen? ¨ Lösung: Constrained Genericty. class SORTED_LIST [T->COMPARABLE] . . end ¨ Erzwingt in Eiffel, dass T Unterklasse von Comparable sein muss, ansonsten Übersetzungsfehler.

Java

Java

Übersicht n Seit 1995 von Sun Microsystems entwickelt. ¨ Stark objektorientiert. ¨ Umfangreiche Klassenbibliothek.

Übersicht n Seit 1995 von Sun Microsystems entwickelt. ¨ Stark objektorientiert. ¨ Umfangreiche Klassenbibliothek. ¨ Automatische Speicherverwaltung. ¨ Plattformunabhängig. ¨ Aus „Generic Java“ entwickelt und offiziell ab Java 1. 5 (Sommer 2004, Codename: Tiger) unterstützt.

Ziele der Java-Implementation n Vollständige Ersetzung der aktuellen Java API durch generische Version. ¨

Ziele der Java-Implementation n Vollständige Ersetzung der aktuellen Java API durch generische Version. ¨ „Retrofitting“ n alten Codes. Vollständige Rückwärtskompabilität. ¨ Alter Code soll ohne Änderung ausführbar bleiben.

Parametertypen n Erlaubte Typarten: ¨ ¨ Klassen sind als Parametertypen erlaubt. Primitive Typen sind

Parametertypen n Erlaubte Typarten: ¨ ¨ Klassen sind als Parametertypen erlaubt. Primitive Typen sind nicht erlaubt. Unteranderem da für sie kein einheitliches Typsystem existiert. Sie müssen jeweils (uneffizient) in ihre Wrapper-Klassen gekapselt werden. z. B. int → Integer, boolean → Boolean ¨ n Übrigens automatisches „Casting“ (Autoboxing) auch ab Java 1. 5. Ausserdem mehrere Typparameter erlaubt.

Klassen Generizität n Beispiel: Die neue java. util. Stack Klasse class Stack<E> extends Vector<E>

Klassen Generizität n Beispiel: Die neue java. util. Stack Klasse class Stack<E> extends Vector<E> { public E push(E item) {. . } public synchronized E pop() {. . } public synchronized E peek() {. . } public boolean empty() {. . } public synchronized int search(Object o) {. . } } n Anwendung: Stack<String> foo = new Stack<String>();

Methoden Generizität n Methoden-Generics unterstützt. ¨ Typangabe (unintuitiverweise) vor Methodenname! Begründung ist leichteres Parsing.

Methoden Generizität n Methoden-Generics unterstützt. ¨ Typangabe (unintuitiverweise) vor Methodenname! Begründung ist leichteres Parsing. Beispiel: Eine vertausche-Operation static <Elem> void swap(Elem[] array, int x, int y) { Elem temp = array[x]; array[x] = array[y]; array[y] = temp; } n Aufrufe auch mit impliziter Typangabe. swap(ints, 1, 3) sort(strings) <Integer>swap(ints, 1, 3) <String>sort(strings)

Bounds n Einschränkung (bounding) der Typen durch ¨ maximal eine Oberklasse und/oder ¨ beliebiger

Bounds n Einschränkung (bounding) der Typen durch ¨ maximal eine Oberklasse und/oder ¨ beliebiger Anzahl von Interfaces. n Beispiel: Sortierte Liste class Sorted. List<T extends Entry implements Comparable> {. . }

Übersetzung (I) Java Implementierung von Generizitäts-Erweiterungen auf Ebene der Übersetzung (Bytecode) Ausführung (JVM) Linux

Übersetzung (I) Java Implementierung von Generizitäts-Erweiterungen auf Ebene der Übersetzung (Bytecode) Ausführung (JVM) Linux Windows . . Plattformen Mobile

Übersetzung (II) n n Oberster Grundsatz: Die Java Virtual Machine wird nicht verändert! Homogener

Übersetzung (II) n n Oberster Grundsatz: Die Java Virtual Machine wird nicht verändert! Homogener Vorgang (für jeden generischen Typen wird einmalig neuer Code generiert) 1. Generische Datentypen werden durch untere Grenze ersetzt (Erasures). 2. Casting geschieht bei Attributzugriffen und Methodenrückgaben. 3. Einsetzung von Bückenmethoden bei kovarianter Vererbung. (siehe später) Ø Vorgang fast analog zum „manuellen“ Vorgang bisher.

Übersetzung (III) Übersetzung in JVM – konformen Code. class Cell<A> { A value; A

Übersetzung (III) Übersetzung in JVM – konformen Code. class Cell<A> { A value; A get. Value(); } class Cell { Object value; Object get. Value(); } . . String f(Cell<String> cell){ return cell. value; } String f(Cell cell){ return (String)cell. value; } Klasse Cell wird nur einmal generiert und kann für alle Parametertypen wiederverwendet werden.

Legacy-Code (I) n Java API soll mit generischen Typen aktualisiert werden. Stack s =

Legacy-Code (I) n Java API soll mit generischen Typen aktualisiert werden. Stack s = new Stack(); geht aber immernoch (sogenannte „Raw Classes“)! Ohne Angabe eines Typparameters wird implizit niedrigste Typschranke angenommen. Hier also: Stack<Object> s = new Stack<Object>(); Ermöglicht „Rückwärts-Kompabilität“, dh. alter Code kann ohne Änderung weiter mit „retrofitted“ API Klassen arbeiten. ¨ Evtl. auch „Vorwärts-Kompabilität“ denkbar. ¨

Legacy-Code (II) n Zuweisungen ¨ Erlaubt Stack s = new Stack<Integer>(); Übersetzer-Warnungen, bei Ø

Legacy-Code (II) n Zuweisungen ¨ Erlaubt Stack s = new Stack<Integer>(); Übersetzer-Warnungen, bei Ø Methodenaufrufem mit veränderten Argumenttypen. Ø Attributzugriffe mit veränderten Typen. s. push(new Integer(5)); //compile-warning ¨ Erlaubt, aber „deprecation“-Warnung, da unsicher. Stack<Integer> s = new Stack();

Kovarianz (I) n Bisher: Invariante Rückgabetypen ¨ n Jetzt: Kovariante Rückgabetypen ¨ n Rückgabetyp

Kovarianz (I) n Bisher: Invariante Rückgabetypen ¨ n Jetzt: Kovariante Rückgabetypen ¨ n Rückgabetyp einer Methode muss identisch sein mit der überschriebenen Methode. Rückgabetyp einer Methode muss Untertyp sein für alle Methoden, die sie überschreibt. Kovarianz wird durch Brückenmethoden realisiert.

Kovarianz (II) class A<T> { T something() {. . } } class B<T implements

Kovarianz (II) class A<T> { T something() {. . } } class B<T implements Comparable> extends A<T> { T something() {. . } } class A { Object something() {. . } } class B extends A { Comparable something() {. . } Object something/*2*/() { return something() } } JVM unterstützt intern auch Methoden mit Signaturen, die sich nur im Rückgabetypen unterscheiden.

Vererbung (I) n Unintuitive Typbeziehung ¨ Linked. List<String> ist Untertyp von List<String>. ¨ List<String>

Vererbung (I) n Unintuitive Typbeziehung ¨ Linked. List<String> ist Untertyp von List<String>. ¨ List<String> ist aber nicht Untertyp von List<Object>.

Vererbung (II) n Naive generische Implementation von Interface Collection: interface Collection<E> { boolean add.

Vererbung (II) n Naive generische Implementation von Interface Collection: interface Collection<E> { boolean add. All(Collection<E> c); boolean contains. All(Collection<E> c); } n Nachteil: ¨ Aufgrund von fehlerender Typbeziehung kann die generische Methode nur eigenen Typen aufnehmen. Collection<Number> = new Collection<Number> col; Collection<Integer> = new Collection<Integer> ints; col. add. All(ints); Typfehler!

Vererbung (III) n Bessere generische Implementation erlaubt kovariante Argumente: interface Collection<E> { <T extends

Vererbung (III) n Bessere generische Implementation erlaubt kovariante Argumente: interface Collection<E> { <T extends E> boolean add. All(Collection<T> c); <T> boolean contains. All(Collection<T> c); } ¨ Auch wenn aktueller Typparameter bei Methodenaufruf implizit übergeben werden kann: Unleserliche und umständliche Notation für häufiges Programmierziel.

Vererbung (IV) Vorangetrieben durch „Variant Generic Java” Wild. Card-Syntax. n 1. Ermöglicht bessere Lesbarkeit

Vererbung (IV) Vorangetrieben durch „Variant Generic Java” Wild. Card-Syntax. n 1. Ermöglicht bessere Lesbarkeit durch anonyme Typparameter. interface Collection<E> { boolean add. All(Collection<? extends E> c); boolean contains. All(Collection<? > c); } 2. Ermöglicht auch Kontravarianz. interface Collection<E> { boolean add. All(Collection<? super E> c); boolean contains. All(Collection<? > c); } n Aber, was trotzdem nicht geht: List<? extends Number> = new List<Integer>;

Exceptions n Nicht vollständig unterstützt. ¨ Generics dürfen nicht von java. lang. Throwableiten. ¨

Exceptions n Nicht vollständig unterstützt. ¨ Generics dürfen nicht von java. lang. Throwableiten. ¨ Typvariablen sind erlaubt in throws – Anweisung. n nicht erlaubt in catch – Anweisung. n

Instanziieren von Parametertypen n Aufgrund von Erasures ist es nicht möglich Parametertypen zu instanziieren.

Instanziieren von Parametertypen n Aufgrund von Erasures ist es nicht möglich Parametertypen zu instanziieren. class Singleton<T> { private T instance; public T get. Instance() { if (instance == null) instance = new T(); } } return instance; Nicht erlaubt!

Reflection n Generische Klassen als Typen bekannt, allerdings keine Kenntnis über aktuelle Typparameter zur

Reflection n Generische Klassen als Typen bekannt, allerdings keine Kenntnis über aktuelle Typparameter zur Laufzeit, da diese beim Übersetzen entfernt werden (erasures). class Sorted. Set<T extends Comparable<T>> { public Sorted. Set() { if (T. class == Date. class) { . . } else if (T. class == Integer. class) { . . } } } Kann nicht funktionieren, da T. class hier immer vom Typ Comparable ist.

Schwächen von Erasures n Unerwartete Fehler aufgrund von gleichen Erasures ¨ class Tool {

Schwächen von Erasures n Unerwartete Fehler aufgrund von gleichen Erasures ¨ class Tool { public void do(Collection<Integer>) {. . } public void do(Collection<String>) {. . } } ¨ class C<A> { A id(A x) {. . } } interface I<A> { A id(A x); } class D extends C<String> implements I<Integer> { String id(String x) {. . } Integer id(Integer x) {. . } }

Zusammenfassung n Vorteil Leichter Übergang zwischen generischem und ungenerischem Code. ¨ Keine neue konkurrierende

Zusammenfassung n Vorteil Leichter Übergang zwischen generischem und ungenerischem Code. ¨ Keine neue konkurrierende Java API. ¨ Anonyme Typparameter (Wildcards). ¨ n Nachteil ¨ ¨ ¨ Keine primitiven Datentypen erlaubt. Uneffizient, da up/down - casting intern immernoch nötig. Kein Wissen über aktuelle generische Typparameter können nicht instanziiert werden. Verschiedene Restriktionen im Zusammenhang mit Erasures

C#

C#

Übersicht n Seit Februar 2001 von Microsoft entwickelt. ¨ Stark objektorientiert. ¨ Umfangreiche Klassenbibliothek.

Übersicht n Seit Februar 2001 von Microsoft entwickelt. ¨ Stark objektorientiert. ¨ Umfangreiche Klassenbibliothek. ¨ Automatische Speicherverwaltung. ¨ Teil des. NET Frameworks ¨ Bald (Mitte/Ende 2004!? ) auch Generics.

Ziel der. Net Implementation n Saubere vollständige Implementation von Generics. ¨ Einführung n neuer

Ziel der. Net Implementation n Saubere vollständige Implementation von Generics. ¨ Einführung n neuer Intermediate Language Typen. Einführung neuer generischer Klassen in das. NET Framework. ¨ Aktuelles erhalten. nicht-generisches. NET Framework bleibt

Parametertypen n Typarten: ¨ Klassen sind als Parametertypen erlaubt. ¨ Primitive Typen sind erlaubt,

Parametertypen n Typarten: ¨ Klassen sind als Parametertypen erlaubt. ¨ Primitive Typen sind erlaubt, da alle Typen (Referenz- und Datentypen) einen gemeinsamen Obertypen haben. n Auch mehrere generische Typen erlaubt.

Klassen Generizität n Beispiel: Eine sortierte Liste class Sorted. List<Entry. Type> where Entry. Type

Klassen Generizität n Beispiel: Eine sortierte Liste class Sorted. List<Entry. Type> where Entry. Type : IComparable{ public void insert(Entry. Type item) {. . } public void remove(Entry. Type item) {. . } public bool contains(Entry. Type item) {. . } public bool empty() {. . } } n Anwendung: Sorted. List<int> ss = new Sorted. List<int>(); n Ausserdem Unterstützung für Structs und Delegates.

Methoden Generizität n Methoden-Generics unterstützt. Typangabe intuitiverweise hinter Methodenname! Beispiel: swap static void swap<Elem>(Elem[]

Methoden Generizität n Methoden-Generics unterstützt. Typangabe intuitiverweise hinter Methodenname! Beispiel: swap static void swap<Elem>(Elem[] array, int x, int y) { Elem temp = array[x]; array[x] = array[y]; array[y] = temp; } n Aufrufe auch mit impliziter Typangabe. swap(ints, 1, 3) sort(strings) swap<int>(ints, 1, 3) sort<string>(strings)

Constraining n Einschränkung (analog zu Java) der Typen durch ¨ ¨ maximal eine Oberklasse

Constraining n Einschränkung (analog zu Java) der Typen durch ¨ ¨ maximal eine Oberklasse und/oder beliebiger Anzahl von Interfaces. n Beispiel: Zwei eingeschränkte Typparameter. pulic class My. List<K, T> where K : Icomparable<K>, IEnumerable where T : Customer { . . } ¨ Notation umständlicher als bei Java!?

Übersetzung (I) Sprachen VB. NET . . C# Java# Übersetzung (MIL) Implementierung von Generizitäts-Erweiterungen

Übersetzung (I) Sprachen VB. NET . . C# Java# Übersetzung (MIL) Implementierung von Generizitäts-Erweiterungen auf Ebene der Ausführung (CLR) (Linux) Windows . . Plattformen Mobile

Übersetzung (II) n Typabhängige Übersetzung: ¨ Für Reference. Types (Klassen) wird einmal generierter gemeinsamer

Übersetzung (II) n Typabhängige Übersetzung: ¨ Für Reference. Types (Klassen) wird einmal generierter gemeinsamer Code wiederverwendet (homogener Vorgang). ¨ Für Value. Types (primitive Typen) wird bei jeder ersten Benutzung spezieller Code generiert (heterogener Vorgang).

Legacy-Code (I) n . NET API erhält zusätzliche generische Klassen. ¨ Ausmass abgesehen von

Legacy-Code (I) n . NET API erhält zusätzliche generische Klassen. ¨ Ausmass abgesehen von Collections Namespace noch unbekannt. n n „Rückwärts-Kompabilität“ wird durch Beibehaltung der alten Klassen gewährleistet. Mischung von generischem und ungenerischem Code nur schwer.

Legacy-Code (II) System. Collections. Generics Comparer<T> Hash. Table Dictionary<K, T> Array. List<T> Queue<T> Sorted.

Legacy-Code (II) System. Collections. Generics Comparer<T> Hash. Table Dictionary<K, T> Array. List<T> Queue<T> Sorted. List Sorted. Dictionary<K, T> Stack<T> ICollection<T> System. Comparable IComparable<T> IComparer<T> Idictionary IDictionary<K, T> Ienumerable IEnumerable<T> IEnumerator<T> IKey. Comparer<T> IList<T>

Typenvarianz n Nur Invariante Rückgabetypen ¨ Rückgabetyp einer Methode muss identisch sein mit der

Typenvarianz n Nur Invariante Rückgabetypen ¨ Rückgabetyp einer Methode muss identisch sein mit der überschriebenen Methode. n Keine Wildcard-Syntax. ¨ Keine Kontravarianz.

Exceptions n Vollständige Unterstützung. ¨ Generics dürfen von System. Exception ableiten. ¨ Typvariablen sind

Exceptions n Vollständige Unterstützung. ¨ Generics dürfen von System. Exception ableiten. ¨ Typvariablen sind erlaubt in throws – Anweisung. n erlaubt in catch – Anweisung, wenn sie vom Typ System. Exception ableiten. n

Instanziieren von Parametertypen können instanziiert werden, wenn sie einen Konstruktor ohne Argumente bieten. ¨

Instanziieren von Parametertypen können instanziiert werden, wenn sie einen Konstruktor ohne Argumente bieten. ¨ Garantie muss als zusätzliches Constraint „new()“ angegeben werden. Beispiel: class Singleton<T> where T : new() { private T instance; public T get. Instance() { if (instance == null) instance = new T(); } } return instance;

Reflection n Volle Reflectionunterstützung von generischen Typen. Type type = typeof(List<int>); n Type-Klasse wird

Reflection n Volle Reflectionunterstützung von generischen Typen. Type type = typeof(List<int>); n Type-Klasse wird erweitert mit speziellen Eigenschaften von generischen Typen: int Generic. Parameter. Position{virtual get; } bool Has. Generic. Parameters{get; } bool Has. Unbound. Generic. Parameters{virtual get; } bool Is. Generic. Parameter{virtual get; } bool Is. Generic. Type. Definition{virtual get; } virtual Type Bind. Generic. Parameters(Type[] type. Args); virtual Type[] Get. Generic. Parameters(); virtual Type Get. Generic. Type. Definition(); ¨ Erlaubt auch Zugriff auf aktuelle Typparameter.

Zusammenfassung n Vorteil Intuitive und vollständige Umsetzung von generischen Typen. ¨ Effizienz. ¨ Vollständige

Zusammenfassung n Vorteil Intuitive und vollständige Umsetzung von generischen Typen. ¨ Effizienz. ¨ Vollständige Typkenntnis zur Laufzeit (Reflection). ¨ n Nachteil Absolute Trennung zwischen generischen und nicht generischem Code. ¨ API kann nicht rückwärtskompatibel umgeschrieben werden. ¨ Keine Kontravarianz. ¨ Umständlichere Notation. ¨

Konklusion

Konklusion

Fazit n Generizität ¨ Sinnvoll und allgemein anerkannt. ¨ Birgt aber auch zusätzliche Komplexität.

Fazit n Generizität ¨ Sinnvoll und allgemein anerkannt. ¨ Birgt aber auch zusätzliche Komplexität. klar, wann angebracht. n Nicht immer Implementationen ¨ Java n Rückwärts-Kompabilität positiv, allerdings grosse Einschränkungen bei Nutzung von generischen Typen. ¨ C# n Gute Unterstützung für generische Typen, aber unklare Konsequenz für. NET Framework.

Referenzen n Adding Generics to the Java Programming Language: Public Draft Specification, Version 2.

Referenzen n Adding Generics to the Java Programming Language: Public Draft Specification, Version 2. 0 Bracha, Cohen, Kemper, Odersky, Stoutamire, Thorup, Wadler n Variant Generic Types n Design an Implementation of Generics for the. NET Common Language Runtime Sun Microsystems Andrew Kennedy, Don Syme n MSDN Article: Introduction to C# Generics Juval Lowy