Das Reflection API 05 - Reflection Ziel Es kommt vor, dass eine Methode ein Objekt als Parameter übergeben bekommt, ohne dass bekannt ist, von welcher Klasse diese Objekt erzeugt wurde. Die weiter Verwendung des Objektes hängt aber davon ab, zu welcher Klasse das Objekt gehört. Beispiel: •Das Graphikprogramm ist von JComponent abgeleitet, damit es flexibel als Applikation, Applet oder interne Applikation genutzt werden kann. •Das Graphikprogramm soll ein JMenuBar an die Elternklasse andocken. Es muss also sicher sein, dass das Elternobjekt die Methode setJMenuBar(JMenuBar) kennt. •Es ist also günstig zu testen ob diese Methode bekannt ist. •Das kann nicht zur Übersetzungszeit passieren, da dort der wahre Typ des Parameters noch nicht bekannt ist. Zur Lösung derartiger Probleme existiert das Reflection API. 05 - Reflection 2 Das Reflection API besteht aus folgenden Klassen: •java.lang.Class beschreibt Klassen •java.lang.reflect.Constructor beschreibt einen Konstruktor •java.lang.reflect.Field beschreibt ein Attribut •java.lang.reflect.Method beschreibt eine Methode •java.lang.reflect.Array beschreibt ein Feld von Objekten •java.lang.reflect.Modifier beschreibt die Modifiziere eines Objectes 05 - Reflection 3 Die Klasse Class Die Klasse Class beschreibt Klassen. D.h. für jede Klasse gibt es genau ein Objekt der Klasse Class, die diese reflektiert. Aus diesem Objekt kann man die vollständige Schnittstellenbeschreibung der Klasse in Erfahrung bringen, sowie auf Konstruktoren, Methoden und Attribute zugreifen. Es gibt keine Konstruktoren. Objekte der Klasse Class werden mit der Methode public Class getClass() der Klasse Object oder mit der Methode public static Class forName(String className) erzeugt. 05 - Reflection 4 Methoden der Klasse Class public Constructor[] getConstructors() liefert ein Feld von Constructor-Objekten für alle in der Klasse definierten Konstruktoren public Class[] getClasses() liefert ein Feld von Class-Objekten für die in der Klasse definierten internen Klassen und Interface public Field[] getFields() liefert ein Feld von Field-Objekten für alle in der Klasse definierten Attribute public Method[] getMethods() liefert ein Feld von Method-Objekten für alle in der Klasse definierten Methoden 05 - Reflection 5 public Constructor getConstructor(Class[] parameterTypes ) liefert das Constructor-Objekt bei die vorgegebene Parameterliste passt. public Field getField(String name) liefert ein Field-Objekte mit dem angegebenen Namen public Method getMethod(String name, Class[] parameterTypes ) liefert ein Method-Objekt für die Methode mit dem angegebenen Namen und passender Parameterliste Falls die Objekte nicht existieren werden die entsprechenden Ausnahmen NoSuchMethodException bzw. NoSuchFieldException ausgelöst. Die Methode public String getName() liefert den vollständigen Namen der Klasse. 05 - Reflection 6 Beispiel Collection col = new TreeSet(); Class colClass = col.getClass(); System.out.println(colClass.getName()); Liefert die Ausgabe java.util.TreeSet 05 - Reflection 7 Die Klasse Method Objekte der Klasse Method beschreiben Methoden von Klassen. Es gibt keinen Konstruktor. Objekte der Klasse Method werden mit den Methoden getMethods bzw. getMethod der Klasse Class erzeugt. 05 - Reflection 8 Methoden der Klasse Method public String getName() liefert den Namen der Methode public Object invoke(Object obj, Object[] args) ruft die Methode des Objektes obj mit den entsprechenden Parametern args auf 05 - Reflection 9 Beispiel JMenuBar mb = new JMenuBar(); try { Class frc = fr.getClass(); Method met = frc.getMethod("setJMenuBar", new Class[]{JMenuBar.class}); met.invoke(fr, new Object[]{mb}); } catch (NoSuchMethodException nsme){} catch (NullPointerException npe){} catch (IllegalAccessException iae){} catch (InvocationTargetException ite){} 05 - Reflection 10