Generics in Java 1.5

 


... [ Seminar BS, WWW und Java ] ... [ Thema Generics in Java ] ... [ Bewertung und Ausblick ] ...

Neuerungen in der Reflection API


generische Klasse Class<T>

Die Klasse Class, deren Instanzen Informationen über eine Java-Klasse enthalten, ist mit der Einführung von Java 1.5 selbst generisch geworden. Der Typparameter entspricht dem Raw Type der Klasse, über die das Class-Objekt Informationen enthält. Umgekehrt enthält jede Klasse in ihrer Klassenvariable class eine Referenz auf ein ebensolches parametrisiertes Class-Objekt.
Es sind nun eine Menge neuer Funktionen hinzugekommen. Unter anderem lässt sich nun herausfinden, mit welchen Parametern eine generische Klasse parametrisiert ist (für die generische Klasse HashMap wären dies z. B. die Parameter K und V). Dies mag verwundern, da ansonsten ja keine Informationen zur Laufzeit über die Generizität vorliegen. Die Generics finden aber allesamt ihre Entsprechungen in der Reflection API, unter anderem deshalb, damit Java-Entwicklungstools wie z. B. Eclipse einfachen Zugriff auf die erweiterten Klasseninformationen haben.
Zurück zur Generizität von Class. Die bereits bekannte Methode newInstance() verwendet nun nämlich den aktuellen Typparameter als Rückgabewert. So entfällt auch hier zumindest im Programmcode ein Downcast:
1: Class<Integer> intClass = Integer.class;
2: Integer i = intClass.newInstance();
Trotzdem können von der Methode newInstance() noch immer die Laufzeitfehler InstantiationException und IllegalAccessException ausgelöst werden. Diese haben aber nichts mit eventuellen Typfehlern zu tun.

getClass()

Für die Methode getClass(), die bereits in der Klasse Object definiert wird, gilt aufgrund der dynamischen Bindung eine besondere Einschränkung. Laut Java API Dokumentation liefert getClass() auf einer Referenz eines beliebigen Objektes des Typs X ein Objekt vom Typ Class<? extends X>. Dies hängt ebenfalls wieder mit der Typsicherheit zusammen. Da bereits zur Compilezeit exakt feststehen muss, von welchem Typ der Rückgabewert der Methode ist, aber nicht bekannt ist, ob das aktuelle Objekt wirklich vom Typ X oder doch eher von dem von X erbenden Typ Y ist, kann nur ebendiese Einschränkung für das zu liefernde Class-Objekt garantiert werden:
1: Vector<String> s = new Vector<String>();
2:
3: Class<Vector<String>> clsTest = s.getClass(); // error - only class of raw type will be returned
4: Class<Vector> clsTest3 = s.getClass(); // error
5: Class<? extends Vector> clsTest2 = s.getClass(); // OK

Neue Interfaces

Wie bereits oben angedeutet, führt Java mit der Version 1.5 erweiterte Reflection-Informationen über Klassen ein. Die erweiterte Klasse Class benutzt dabei auch einige neue Interfaces. Eins davon ist das Interface Type, das die Subinterfaces TypeVariable, ParametrizedType, WildcardType und GenericArrayType hat. Auf den genauen Aufbau dieser Schnittstellen soll hier nicht weiter eingegangen werden; der interessierte Leser sei an die Java API Documentation verwiesen. Es soll hierdurch jedoch gezeigt werden, dass die neuen syntaktischen Elemente wie gewohnt ihre Entsprechungen in der Reflection API finden.
Stellvertretend sei hier das Interface GenericDeclaration vorgestellt, das vom Interface TypeVariable benutzt und von den Klassen Class, Constructor und Method implementiert wird:
1: public interface GenericDeclaration {
2: public abstract TypeVariable[] getTypeParameters();
3: }
Man kann sich hier gut vorstellen, wie man mit Hilfe dieses Interfaces eine Klasse direkt "fragen" kann, mit welchen Typparametern sie parametrisiert wurde. Ähnliche Hilfestellungen liefern die anderen Interfaces und neuen Methoden der Klasse Class entsprechend.

... [ Seminar BS, WWW und Java ] ... [ Thema Generics in Java ] ... [ Neuerungen in der Reflection API ] ... [ Bewertung und Ausblick ] ...

Valid XHTML 1.0 Strict