Reflection API ETIS SS05 Gliederung • Motivation – Einsatzgebiete – Metaprogrammierung • • • • Klasse Class Zugriff auf Klassenbestandteile Erzeugen von Objekten Manipulieren von Objekten – Felder setzen – Methodenaufruf • Zusammenfassung Reflection API ETIS SS05 - Nadine Fröhlich 2 Motivation - Allgemein • Bestandteile: – Core Reflection API: java.lang.reflect (seit JDK 1.1) – Klassen: Method, Field, Modifier, ... – außerdem: java.lang - Klassen: Object + Class • Spiegelt Klassen, Schnittstellen, Objekte in aktueller JVM wider (Metainformationen) – Metainformationen werden automatisch vom Compiler generiert • Ermöglicht, dynamisch zur Laufzeit: – Zugriff auf Informationen über Klassen und deren Bestandteile – Teilweise Manipulation dieser Metainformationen Reflection API ETIS SS05 - Nadine Fröhlich 3 Motivation – konkrete Möglichkeiten • Laden und Instanzieren von Klassen, deren: – Name zur Compilezeit unbekannt – Quellcode nicht vorhanden – Aufbau nicht bekannt ist • Informationen zu Klassen: Methoden, Membervariablen, Superklassen, … • Informationen zu Interfaces: Methoden, Konstanten • Methodenaufruf + Setzen von Membervariablen, deren Name erst zur Laufzeit bekannt • Arrays kreieren, deren Größe + Komponententyp zur Laufzeit nicht bekannt + Veränderung der Komponenten • … Reflection API ETIS SS05 - Nadine Fröhlich 4 Einsatzgebiete • JavaBeans – Properties ermitteln (anhand der get- und set-Methoden) – Werte der Properties auslesen + setzen • JUnit – Test-Methoden ermitteln und ausführen (Vorsilbe test) • JDBC – Treiber anhand seines Namens laden • Objekt-Relationale-Mapper, Serialisierung, Debugger, GUI-Builder, Class-Browser, Plugins, … Reflection API ETIS SS05 - Nadine Fröhlich 5 Metaprogrammierung • Reflection ist eine (abgeschwächte) Form der Metaprogrammierung • normal: - Programm kennt Daten, aber nicht sich selbst • Metaprogrammierung: - Programme als Daten - Programm hat Zugriff auf sich selbst - Programm liegt in selber Präsentation wie Daten vor Reflection API ETIS SS05 - Nadine Fröhlich 6 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(“java.awt.Button“); Reflection API ETIS SS05 - Nadine Fröhlich 7 Zugriff auf Klassenbestandteile I • für dynamischen Zugriff auf Klassenbestandteile Klassen: Constructor, Method und Field • Instanzen dieser Klassen mit Methoden der Klasse Class erzeugt – Field fields [] = c.getFields(); – Field fields [] = c.getDeclaredFields(); – Field field = c.getField(“name“); • Hinweis: mit erhaltenen Field-Objekten sind mehrere Instanzen bearbeitbar (d.h. beim Setzen der Felder ist das betroffene Objekt mit anzugeben) Reflection API ETIS SS05 - Nadine Fröhlich 8 Zugriff auf Klassenbestandteile II • Ermittlung der Methoden einer Klasse: Method m[] = c.getMethods(); Method m[] = c.DeclaredMethods(); Class param[] = new Class[] {Object.class} Method m = c.getMethod(“add“, param) • Weiterhin ermittelbar: – Interfaces, Superklassen – Packagename, Name der Klasse – Modifier (z.B. public, final) – ob eine Datentyp primitiv ist Reflection API ETIS SS05 - Nadine Fröhlich 9 Erzeugen von Objekten • Normal: – Person p = new PersonBean(); • Mit Reflection: – Class c = Class.forName(“demo.PersonBean“); – Person p = (Person) c.newInstance(); • Vorgehen ermöglicht Zugriff auf Klasse, die während Erstellung der Anwendung unbekannt ist. • Im obigen Beispiel Zugriff auf: – jede beliebige Klasse, die Interface Person implementiert + – evtl. aus Properties-Datei stammt Reflection API ETIS SS05 - Nadine Fröhlich 10 Felder setzen • Normal: – p.pname = “Lisa“; • Mit Reflection: – Class c = p.getClass(); – Field name = c.getDeclaredField(“pname“); – name.set(p, “Lisa“); Reflection API ETIS SS05 - Nadine Fröhlich 11 Methodenaufruf • Normal: p.setFirstName(“Maria“); • Mit Reflection: Class c = p.getClass(); //Parametertypen setzen Class argDef[] = {String.class}; Method m = c.getMethod(“setFirstName“, argDef); //Parameterwerte setzen Object arg[] = {“Maria“}; m.invoke(p, arg); Reflection API ETIS SS05 - Nadine Fröhlich 12 Zusammenfassung • Reflection einzusetzen, wenn hohe Flexibilität gefordert: – Klassen zur Laufzeit einzubinden, die zur Compile-Zeit noch unbekannt sind – Klassen-Schnittstellen nicht durch Interfaces oder abstrakte Klassen definiert, sondern Schnittstellenkonventionen und -mustern folgen (wie Java Beans) • Fast vollständige Kontrolle über Objekte möglich: – Methodenname, Parameter, Attribute, Klassennamen in Dateien ablegbar • Aber: – z.T. etwas geringere Performance – Keine Prüfung des Compilers auf Korrektheit der Datentypen • Daher: – Reflection API nur einsetzen, wo wirklich erforderlich Reflection API ETIS SS05 - Nadine Fröhlich 13 Quellen • • • http://www.dpunkt.de/java/Die_Sprache_Java/Objektorientierte_Progra mmierung_mit_Java/70.html http://www.jeckle.de/vorlesung/java/script.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 http://www.voelter.de/data/presentations/meta.ppt Wutka, M., J2EE Developer‘ s Guide, Markt+Technik, München, 2002 • • • diese Dokumente existieren nicht mehr im Netz... http://www.rz.fhtw-berlin.de/hjp3/k100268.html#kapitelreflection http://www.ifs.tuwien.ac.at/~mbach/misc/JavaVsSmallTalk/node35.html • • • • Reflection API ETIS SS05 - Nadine Fröhlich 14 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(setXXX und getXXX) • Introspection basiert auf Reflection, aber höhere Sicht – wichtige Methoden: – java.beans.Introspector – java.beans.PropertyDescriptor Reflection API ETIS SS05 - Nadine Fröhlich 15