Motivation Reflection API • Core Reflection API: java.lang.reflect • Seit JDK 1.1 integraler Bestandteil der JavaKlassenbibliothek • Ermöglicht: – Laden und Instanzieren von Klassen, ohne dass Name zur Compilezeit bekannt – Methoden aufrufen und auf Membervariablen zugreifen, wenn Name erst zur Laufzeit des Programmes bekannt Reflection API 1 Notwendigkeit • Ermöglicht Zugriff auf (public) Informationen über Klassen (Metainformationen), deren: – Quellcode nicht vorhanden und/oder – Aufbau nicht bekannt ist • Für Entwicklung der Beans- und SerialisierungsAPIs benötigt • Für Debugger, GUI-Builder, Class-Browser Reflection API 2 Ausgangspunkt: Klasse Class • im Paket java.lang • Instanzen dieser Klasse repräsentieren Klassen + Interfaces laufender Java Anwendung • Instanzen automatisch durch JVM konstruiert • Instanz abfragbar, wenn: – Objekt der Klasse verfügbar, mit: Class c = o.getClass(); – Name der Klasse zur Compilezeit bekannt, mit: Class c = java.awt.Button.class; – Klassenname zur Lauf- aber nicht zur Compilezeit, mit: Class c = Class.forName(strg); Reflection API 3 Zugriff auf Klassenbestandteile • für dynamischen Zugriff auf Klassenbestandteile Klassen: Constructor, Method und Field – repräsentieren entsprechenden Klassenbestandteil – haben Methoden zum Aufrufen (Constructor, Method) oder – Methoden zum Auslesen + Setzen (Field) • Instanzen nicht direkt erzeugt, sondern mit Methoden der Klasse Class z.B. getField() erst Class-Objekt, dann Bestandteile ermitteln Reflection API 4 Metainformationen • Klassennamen ermitteln: Class c = o.getClass(); System.out.println(c.getName()); • Ermittlung der Methoden einer Klasse: Class c = o.getClass(); Method m[] = c.getMethods(); for (int i = 0; i < m.length; i++){ System.out.println(‘‘Methode:‘‘+ m[i].getName()); } Reflection API 5 Erzeugen von Objekten • Normal: Person p = new PersonBean(); • Mit Reflection: Class c = Class.forName(“demo.PersonBean“); Person p = (Person) c.newInstance(); • Ermöglicht Zugriff auf Klasse, die während Erstellung der Anwendung unbekannt – jede beliebige Klasse, die Interface Person implementiert – evtl. aus Property-Datei Reflection API 6 Setzen von Werten • Normal: p.setFirstName(“Maria“); • Mit Reflection: Class c = p.getClass(); Class argDef[] = {String.class}; Method m = c.getMethod(“setFirstName“, argDef); Object arg[] = {“Maria“}; m.invoke(p, arg); Reflection API 7 Java Beans • normale Java-Klassen, die Design und Namensmuster folgen (Verarbeitungslogik) • parameterloser Konstruktor • definieren Properties (Objekteigenschaften) • Properties über getter/setter-Methoden abfragen + ändern, d.h. folgen Muster: setXXX()-Methode zum Setzen getXXX-Methode zum Auslesen XXX steht für Namen der Property Reflection API 8 Java-Beans + Reflection • Reflection (eigentlich Introspection) angewandt, um Properties der BeanKlasse zur Laufzeit zu ermitteln, auszulesen bzw. neu zu setzen • Properties spezifisch für jede Bean-Klasse, folgen aber Muster • Anwendung erkennt Properties der Bean-Klasse an diesem Muster und sucht nach setXXX und getXXX Reflection API 9 Zusammenfassung(I) • Reflection einzusetzen, wenn: – Klassen zur Laufzeit einzubinden, die zur Compile-Zeit noch nicht bekannt – Schnittstellen der Klassen nicht durch Interfaces oder abstrakte Klassen definiert, sondern Schnittstellenkonventionen und -mustern folgen (Java Beans) • Fast vollständige Kontrolle über Objekte: – Methodenname und Übergabeparameter in Dateien ablegbar, (äquivalent) Attribute Reflection API 10 Zusammenfassung(II) • • • • Hohe Flexibilität Aber: mehrfaches an Quelltext Performanceeinbußen Keine Prüfung des Compilers auf Korrektheit der Datentypen • Daher: Reflection API nur einsetzen, wo wirklich erforderlich!!! Reflection API 11 Quellen • http://www.dpunkt.de/java/Die_Sprache_Java/Objektorientierte_ Programmierung_mit_Java/70.html • http://www.rz.fhtw-berlin.de/hjp3/k100268.html#kapitelreflection • http://www.ifs.tuwien.ac.at/~mbach/misc/JavaVsSmallTalk/node 35.html • http://www.jeckle.de/vorlesung/java/kap3.html#reflectionAPI • http://java.sun.com/docs/books/tutorial/reflect/ • Wille, S., Go To Java Server Pages, Addison-Wesley, München, 2001 • Holubek, A.: Willkommen im Dungeon, Java Magazin,3/2000, S.20: java-praxis Reflection API Reflection API 12 Lösung der Zusatzaufgabe Properties p = new Properties(); p.setProperty("12", "maus"); test(p); System.out.println(p.getProperty("12")); public static void test(Properties p){ Class c = p.getClass(); Class args[] = {String.class, String.class}; try{ Method m = c.getMethod("setProperty", args); Object a[] = {"12", "Maria"}; m.invoke(p, a); } catch (NoSuchMethodException exc){ exc.printStackTrace(); } catch (IllegalAccessException exc){ exc.printStackTrace(); }catch (InvocationTargetException exc){ exc.printStackTrace(); } Reflection API 13