Inhaltsverzeichnis Inhaltsverzeichnis 1 Einleitung 1 1.1 Generizität................................ 1 1.2 Syntax.................................. 2 2 Realisierung 2 2.1 Compilierung generischer Klassen................... 2 2.2 Probleme bei Verwendung generischer Klassen............ 3 3 Praxis 4 3.1 Programmieren mit gernerischen Klassen............... 4 4 Wildcards 6 5 Schnittstellen 7 5.1 Generische Schnittstellen........................ 7 6 Class<T> 8 6.1 Java-Interne Bedeutung der Klasse................... 8 1 Einleitung 1.1 Generizität Motivation Parametrierbare Elemente (Datentyp) Wiederverwendbarkeit des Codes Typsicherheit: Typenfehler werden beim Kompilieren erkannt Vermeidung von expliziten Cast (Collections mit Elementen vom Typ Object) Bestandteile Generische Klassen Generische Schnittstellen Generische Methoden
1.2 Syntax Generische Klassen Formaler Typ-Parameter wird in spitzen Klammern angegeben TYP Innerhalb des Quelltext ist nun der formale Typ Parameter TYP bekannt 1 public class Punkt <TYP> { 2 private TYP x ; 3 private TYP y ; 4 5 p u b l i c Punkt (TYP x, TYP y ) { 6 t h i s. x = x ; 7 t h i s. y = y ; 8 } 9 10 p u b l i c TYP getx ( ) { 11 r e t u r n x ; 12 } 13 14 public String tostring ( ) { 15 r e t u r n ( "x = " + x + ", y = " + y ) ; 16 } 17 } Aktuell parametrisierte Klassen Eine konkrete Ausprägung einer generischen Klasse heißt aktuell parametrisierte Klasse 1 p u b l i c c l a s s T e s t { 2 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 3 Punkt <Integer > intpunkt = new Punkt <Integer > ( 1, 2) ; 4 Punkt <Double> doublepunkt = new Punkt <Double> ( 1. 23, 4.45) ; 5 Punkt <String > stringpunkt = new Punkt <String > ( "Punkt1", "Punkt2" ) ; 6 7 System. out. p r i n t ( "Test mit dem Integer " ) ; 8 System. o u t. p r i n t l n ( i n t P u n k t ) ; 9 } 10 } 2 Realisierung 2.1 Compilierung generischer Klassen Code Sharing Für eine generische Klasse wird nur eine Bytecode-Datei generiert Der Bytecode der generischen Klasse wird für alle parametrisierten Klassen verwendet Im Klassennamen der Bytecode-Datei fällt der Typ-Parameter weg 2
Code Sharing Die generische Klasse ist Polymorph Sie nimmt je nach Typ-Parameter verschiedene Gestalt an Aktuell Parametrisierte Klassen haben keine Vererbungsbeziehung und stehen hirarchisch auf einer Ebene Sharable Bytecode wird auch mit dem Begriff Raw-Type verbunden Type Erasure Technik Der Typ-Parameter TYP wird durch Object ersetzt 1 c l a s s GenerischeKlasse <TYP> { 2 TYP v a r i a b l e ; wird zu 1 c l a s s G e n e r i s c h e K l a s s e { 2 Object v a r i a b l e ; TypeErasure Technik Es können nur Datentypen verwendet werden die Referenztypen sind (von der Basisklasse Object abgeleitet sind) Compiler fügt explizite Casts ein 1 I n t e g e r i = ( I n t e g e r ) p a r a m e t r i s i e r t e K l a s s e. get ( ) ; wird zu 1 I n t e g e r i = p a r a m e t r i s i e r t e K l a s s e. get ( ) ; 2.2 Probleme bei Verwendung generischer Klassen Einschränkungen Ein formaler Typ-Parameter darf nicht bei der Definition von Klassenvariablen und -methoden verwendet werden. Von einem formalen Typ-Parameter kann kein Objekt - beispielsweise mit new TYP angelegt werden. 3
Einschränkungen Eine Referenzvariable auf ein Array, das Referenzen auf Objekte aktuell parametrisierter Klassen enthalten soll, darf nur unter Verwendung der Unbounded Wildcards? angelegt werden. Auch das Anlegen eines Array-Objektes unter der Verwendung eines aktuellen oder formalen Typ-Parameteres ist unzulässig und es muss wiederum die Unbounded Wildcard? eingesetzt werden. Ein korrektes Array ist beispielsweise: Punkt<?>[ ] arr = new Punkt<?>[10] Einschränkungen Ein formaler Typ-Parameter darf nicht in Verbindung mit dem instanceof - Operator verwendet werden. Eine Typ-Prüfung ref instanceof TYP ist generell nicht zulässig. Aber beruhigend: Der Compiler erkennt ein Verstoß gegen diese Einschränkungen. 3 Praxis 3.1 Programmieren mit gernerischen Klassen Klassen mit mehreren formalen Typ-Parametern Es können auch mehrere formale Parameter verwendet werden, die mit Kommata getrennt angegeben werden. 1 c l a s s GenerischeKlasse <TYP1, TYP2,..., TYPN) { 2 TYP1 var1 ; 3 TYP2 var2 ; 4 5 public methode (TYP1 arg1, TYP2 arg2 ) { 6... 7 } 8 } Vererbungsbeziehungen 1. Generische Klasse erweitert generische Vaterklasse 2. Generische Klasse erweitert herkömmliche Vaterklasse 3. Herkömmliche Klasse erweitert generische Vaterklasse 4
Generische Klasse erweitert generische Vaterklasse 1. Der Parameter TYP wird an die Vaterklasse durchgereicht. 1 c l a s s Kindklasse <TYP> e x t e n d s V a t e r k l a s s e <TYP>) { 2... 2. Die Kindklasse leitet von der aktuell parametrisierten Vaterklasse ab. Die (parametrisierten) Methoden der Vaterklasse können nur mit Referenzen auf Objekte vom Typ Integer aufgerufen werden. 1 c l a s s Kindklasse <TYP> e x t e n d s V a t e r k l a s s e < I n t e g e r >) { 2... Generische Klasse erweitert herkömmliche Vaterklasse Die Kindklasse erbt die nicht generischen Methoden der Vaterklasse. 1 c l a s s Kindklasse <TYP> e x t e n d s V a t e r k l a s s e ) { 2... Herkömmliche Klasse erweitert generische Vaterklasse Die Kindklasse erbt die nicht generischen Methoden der Vaterklasse. 1 c l a s s Kindklasse extends Vaterklasse < Integer >) { 2... Hinweis Der formale Typ-Parameter muss zwingend durch einen aktuellen ersetzt werden. Eigenständig generische Methoden Beschreibung Eigenständig generische Methoden sind parametrisierte Methoden innerhalb einer nichtgenerischen Klasse. Realisierbar sind: Klassenmethoden Instanzmethoden Konstruktoren Eigenständig generische Methoden 1 p u b l i c c l a s s E i n f a c h e K l a s s e { 2 p r i v a t e I n t e g e r daten ; 3 4 / / E i g e n s t a e n d i g g e n e r i s c h e r K o n s t r u k t o r 5 p u b l i c <TYP> E i n f a c h e K l a s s e ( T arg ) { 6 System. o u t. p r i n t l n ( a r g ) ; 7 } 8 9 / / E i g e n s t a e n d i g g e n e r i s c h e Methode 10 p u b l i c <TYP> void ge n er i sc he M et h od e ( T arg ) { 11... 12 } 1 5
4 Wildcards Theorie Prinzip Erinnerung Zwischen aktuell parametrisierten Klassen besteht keine Vererbungshierarchie Lösung Um Referenzvariablen die auf Objekte beliebig parametrisierter Klassen generischen Typs zeigen definieren zu können gibt es in Java sog. Wildcards notwendig. 1. Unbounded Wildcard 2. Upper Bound Wildcard 3. Lower Bound Wildcard Unbounded Wildcard Anwendung Keine Einschränkung durch welchen Typ die Wildcard ersetzt werden kann. 1 Punkt <?> ref = new Punkt <Integer > 2 / / oder 3 Punkt <? e x t e n d s Object > r e f = new Punkt < I n t e g e r > Unbounded Wildcards können nur für Referenzvariablen Arrays von Referenzen genutzt werden. Upper Bound Wildcard Anwendung Die Upper Bound Wildcard erlaubt nur Elemente die von der Upper Bound abgeleitet sind. (beschränkt nach oben) 1 <? e x t e n d s Klasse > 2 3 Punkt <? e x t e n d s Number> r e f ; 4 Punkt <Integer > refi = new Punkt <Integer > ( ) ; 5 Punkt <Double> refd = new Punkt <Double > ( ) ; 6 Punkt <String > refs = new Punkt <String > ( ) ; Upper bound Wildcards können für Referenzvariablen Arrays von Referenzen Bei Klassen (später mehr dazu) genutzt werden. 6
Upper Bound Wildcard Lower Bound Wildcard Anwendung Die Lower Bound Wildcard erlaubt nur Elemente von denen das Element selber abgeleitet wurde also deren Vaterklassen. (beschränkt nach unten) 1 <? s u p e r Klasse > 2 3 Punkt <? e x t e n d s Number> r e f ; 4 Punkt <Integer > refi = new Punkt <Integer > ( ) ; 5 Punkt <Double> refd = new Punkt <Double > ( ) ; 6 Punkt <String > refs = new Punkt <String > ( ) ; Lower bound Wildcards können für Referenzvariablen Arrays von Referenzen Klassen (in Kombination mit der Unbounded Wildcard) genutzt werden. Lower bounded Wildcard 5 Schnittstellen 5.1 Generische Schnittstellen Grundlagen 7
Man kann in Java von nur einer Klasse ableiten, jedoch mehrere Schnittstellen implementieren Ohne Ersetzung der formalen Typ-Parameter Grundlagen 1 i n t e r f a c e GenerischesInterface <TYP1, TYP2, TYPN> { 2 public void methode1 (TYP1 param ) ; 3 p u b l i c void methode2 ( ) ; 4 } 1. Mit Ersetzung der formalen Typ-Parameter 2. Ohne Ersetzung der formalen Typ-Parameter Lower bounded Wildcard Beispiel: Comparable-Schnittstelle Aus dem Paket java. lang Ermöglicht, dass mit public static void sort (Object \[ \] a) aus java. util sortiert werden kann Für eigene Klassen muss compareto (...) implementiert werden 6 Class<T> 6.1 Java-Interne Bedeutung der Klasse Interne Bedeutung Jeder Typ wird durch ein Objekt der Klasse class <TYP> repräsentiert. Dieses Objekt enthält alle Eigenschaften des Typs Für jede Schnittstelle, Klasse, jedes Array und jeden elementaren Datentyp existiert genau ein Objekt der Klasse class <TYP> Es können keine Class<T> Objekte vom Programmierer angelegt werden 8
Möglichkeiten Mit Hilfe der Instanzmethode getclass () wird eine Referenz auf das hinter dem Objekt stehende class <TYP> zurückgegeben Mit Hilfe dieser Referenz lassen sich, dann verschiedene Methoden aufrufen. Gibt es noch Fragen? Vielen Dank für die Aufmerksamkeit! 9