Einstieg

Das Java Reflection API erlaubt es uns mit Klassen zu arbeiten, obwohl die Klasse im Detail zur Compile-Zeit nicht bekannt ist. Wir können zum Beispiel die Datenelemente eines JavaBeans ermitteln oder auch Klassen dynamisch nachladen.

Das dynamische nachladen von Klassen wird häufig bei Treiberklassen wie z.B. für Datenbankenanbindungen angewendet.

Class.forName("org.h2.Driver").newInstance();
            

Mit dieser Anweisung laden wir die Treiberdatei für eine H2 Datenbank und legen eine neue Instanz an.

Die Klasse Class

Die Klasse Class ist ein zentraler Bestandteil der Java Reflection API. Für jede Klasse und für jedes Interface existiert ein Objekt der Klasse Class, welche die benötigten Informationen über die Klasse bzw. des Intefaces enthalten. So können wir z.B. mithilfe der Klasse Class die definierten Konstruktoren, Felder und Methoden bestimmen.

Um diese Informationen zu erhalten, sind in der Klasse Class folgende Methoden definiert:

  • public Constructor[] getConstructors()
  • public Field[] getFields()
  • public Method[] getMethods()
  • public Constructor[] getDeclaredConstructors
  • public Field[] getDeclaredFields()
  • public Method[] getDeclaredMethods()

Wenn wir genauer hinschauen, entdecken wir 3 Methoden, die in zwei Ausführungen auftreten. Ein Unterschied ist, dass die Methoden ohne "Declared" alle jeweils öffentlichen Elemente und die mit "Declared" alle Elemente (auch die nicht öffentlichen) liefern. Ein weiter Unterschied besteht darin, dass die Methoden ohne "Declared" auch die Elemente der Basisklassen liefert, wohingegen die Methoden mit "Declared" nur die Elemente liefert, die direkt in der Klasse definiert sind.

Eine Möglichkeit an das Class Objekt eines Objektes heranzukommen ist der Aufruf von getClass() auf das entsprechende Objekt. Möchten wir an das Class Objekt eines bekannten Typs oder auch eines Interfaces gelangen hilft uns das Schlüsselwort class weiter.

Beispiel zur Ermittlung der öffentlichen Methoden

In diesen Abschnitt entwickeln wir ein Beispielprogramm, bei dem wir die öffentlichen Methoden eines Objektes bestimmen, dessen Typ bei der Ausgabe nicht bekannt ist. Nachfolgend definieren wir zunächst eine Klasse SomeClass. Später wollen wir ein Objekt dieser Klasse auf öffentliche Methoden hin untersuchen.

public class SomeClass {
  public int getAnswer() {
    return 42;
  }
  public String getAnswerAsString() {
    return "The answer is 42";
  }
  private double getDoubleAnswer() {
    return 42.0;
  }
}
itmapa.de - X2H V 0.21

Nachfolgend definieren wir ein kleines Programm mit einer Methode printPublicMethods, welche ein Object des Typs SomeClass übergeben bekommt. Innerhalb dieser Methode ist der konkrete Typ des Objects unbekannt, sodass wir ohne Reflection nur auf die in Object definierten Methoden zugreifen können. Mithilfe von Reflection geben wir in dieser Methode jedoch alle (auch die geerbten) öffentlichen Methoden aus.

public class SomeClass {
  public int getAnswer() {
    return 42;
  }
  public String getAnswerAsString() {
    return "The answer is 42";
  }
  private double getDoubleAnswer() {
    return 42.0;
  }
}
itmapa.de - X2H V 0.21

Die Ausführung des Programms führt zu folgender Ausgabe auf der Systemausgabe:

public int refl.SomeClass.getAnswer()
public java.lang.String refl.SomeClass.getAnswerAsString()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
            

Die Ermittlung der öffentlichen Konstruktoren und Felder erfolgt analog der Ermittlung der öffentlichen Methoden.

Stefan Middendorf, Reiner Singer, Jön Heid
Programmierhandbuch und Referenz für die Java 2 - Plattform, Standard Edition
4.16 Das Reflection API


Christian Ullenboom
Java ist auch eine Insel
25 Reflection und Annotationen


http://acadopus.de/
Java: Magic of Reflection, Teil 1
Java: Magic of Reflection, Teil 2