Reflection API ETIS SS05
Gliederung Motivation Klasse Class Zugriff auf Klassenbestandteile Einsatzgebiete Metaprogrammierung Klasse Class Zugriff auf Klassenbestandteile Erzeugen von Objekten Manipulieren von Objekten Felder setzen Methodenaufruf Zusammenfassung Reflection API ETIS SS05 - Nadine Fröhlich
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
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
Einsatzgebiete JavaBeans JUnit JDBC 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
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
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
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
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
Erzeugen von Objekten Normal: Mit Reflection: 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
Felder setzen Normal: Mit Reflection: p.pname = “Lisa“; Class c = p.getClass(); Field name = c.getDeclaredField(“pname“); name.set(p, “Lisa“); Reflection API ETIS SS05 - Nadine Fröhlich
Methodenaufruf Normal: Mit Reflection: p.setFirstName(“Maria“); 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
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
Quellen http://www.dpunkt.de/java/Die_Sprache_Java/Objektorientierte_Programmierung_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
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