Java Reflection (Java Reflection) Detaillierte


Reflexion ist in der Programmiersprache Java eine der Eigenschaften, die die Ausführung von Java-Programmen erlaubt auf eigenen Kontrolle, oder "Selbst-Prüfung", und kann direkt Attribut, um die interne Betriebsverfahren.Zum Beispiel kann es sich eine Java-Klasse Namen jedes Mitglieds und Display.

Java, in der praktischen Anwendung dieser Fähigkeit kann genutzt werden, sind nicht viele, aber in anderen Programmiersprachen diese Funktion einfach nicht vorhanden.Zum Beispiel, Pascal, C oder C + + gibt es keine Möglichkeit, die Definition der Funktion im Programm-Informationen zu erhalten.

JavaBean ist eine Reflexion der praktischen Anwendung, ermöglicht es Visualisierungs-Tools Betriebssystem Software-Komponenten.Diese Tools werden dynamisch durch Reflektion geladen und bekommen Java-Komponenten (Klassen) der Immobilie.

1. Ein einfaches Beispiel

Betrachten Sie die folgenden einfachen Beispiel, lasst uns sehen, wie die Arbeit Nachdenken.


Import java.lang.reflect .*;
public class DumpMethods {
public static void main (String args []) {
try {
Klasse C = Class.forName (args [0]);
Methode m [] = c.getDeclaredMethods ();
for (int i = 0; i m.length; i + +)
System.out.println (m [i] ToString ().);
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Anweisung ausgeführt wird wie folgt:
java DumpMethods java.util.Stack

Es ist die resultierende Ausgabe ist:
öffentlichen java.lang.Object java.util.Stack.push (Object)

public synchronized java.lang.Object java.util.Stack.pop ()

public synchronized java.lang.Object java.util.Stack.peek ()

public boolean java.util.Stack.empty ()

public synchronized int java.util.Stack.search (Object)

Diese listet die Namen der einzelnen Verfahren java.util.Stack Klasse und ihre Qualifikation und Rückgabetyp.

Dieses Programm verwendet Class.forName an die angegebene Klasse zu laden, rufen Sie dann an dieser getDeclaredMethods Klasse bekommen definiert eine Methode Liste.java.lang.reflect.Methods wird verwendet, um eine einheitliche Methode für eine Klasse von einer Klasse beschreiben.


2. Started Reflection

Für die Reflexion der Klasse, wie die Methode, kann in der java.lang.relfect Paket gefunden werden.Bei Verwendung dieser Klassen müssen folgen drei Schritten: Der erste Schritt ist, um die Klasse Sie java.lang.Class Objekt betreiben zu bekommen.Laufen in der Java-Programm, mit dem java.lang.Class Klasse zur Beschreibung der Klassen und Schnittstellen.

Hier ist ein Class-Objekt Methoden zu erhalten:
Klasse C = Class.forName ("java.lang.String");

Diese Aussage zu bekommen String-Klasse Klasse Objekt.Es geht auch anders, wie die folgende Aussage:
Klasse C = int.class;

Oder
Klasse C = Integer.TYPE;

Sie erhalten grundlegende Arten von Klasse Informationen.Besuchen Sie eine der letzteren Methode ist die grundlegende Art der Verpackung (zB Integer) in den vordefinierten Feld TYPE.

Der zweite Schritt ist die Methode aufrufen, wie getDeclaredMethods alle Methoden in der Klasse definiert Liste zu erhalten.

Sobald Sie diese Informationen erhalten, kann der dritte Schritt durchgeführt werden - und verwenden Sie die Reflection-API, um die Informationen, wie Sie den folgenden Code zu manipulieren:
Klasse C = Class.forName ("java.lang.String");

Methode m [] = c.getDeclaredMethods ();

System.out.println (m [0] ToString ().);

Es wird als Text ausdrucken String-Methode in den ersten Prototyp definiert.

Im Beispiel unten, die drei Schritte für den Umgang mit bestimmten Anwendungen zum Nachdenken nutzen, um Beispiele zu stellen.

Analog instanceof-Operator

Nach Informationen erhalten Klasse, in der Regel ist der nächste Schritt auf dem Class-Objekt, einige grundlegende Probleme zu lösen.Zum Beispiel kann Class.isInstance Methode zur Simulation der instanceof-Operator werden:
class A {
}

public class instance1 {
public static void main (String args []) {
try {
Klasse cls = Class.forName ("A");
boolean b1 = cls.isInstance (new Integer (37));
System.out.println (B1);
boolean b2 = cls.isInstance (neue A ());
System.out.println (b2);
} Catch (Throwable e) {
System.out.println (e);
}
}
}

In diesem Beispiel wird eine Klasse von Objekten der Klasse A, und dann prüfen, ob ein Objekt ist eine Instanz von A.Integer (37) ist nicht, aber die neue A () ist.


3. Um Klassenmethoden

Suchen Sie eine Klasse definiert, welche Methoden, dies eine sehr wertvolle Verwendung von sehr grundlegenden Reflexion ist.Der folgende Code führt diese Nutzung:
Import java.lang.reflect .*;

public class method1 {
private int f1 (Object p, int x) {wirft NullPointerException
if (p == null)
throw new NullPointerException ();
return x;
}

public static void main (String args []) {
try {
Klasse cls = Class.forName ("method1");
Methode methlist [] = cls.getDeclaredMethods ();
for (int i = 0; i methlist.length; i + +) {
Methode m = methlist [i];
System.out.println ("name =" + m.getName ());
System.out.println ("decl class =" + m.getDeclaringClass ());
Klasse pVEC [] = m.getParameterTypes ();
for (int j = 0; j pvec.length; j + +)
System.out.println ("param #" + j + "" + pVEC [j]);
Klasse EVEC [] = m.getExceptionTypes ();
for (int j = 0; j evec.length; j + +)
System.out.println ("exc #" + j + "" + EVEC [j]);
System.out.println ("return type =" + m.getReturnType ());
System.out.println ("-----");
}
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Dieses Programm zunächst eine Beschreibung der method1 Klasse, dann rufen Sie getDeclaredMethods zu einer Reihe von Method-Objekte, die in der Klasse definiert werden, zu beschreiben jede der Methoden, einschließlich der öffentlichen Methoden, geschützten Verfahren Paket private Methoden und Verfahren zu erhalten.Wenn Sie das Programm auf getMethods getDeclaredMethods ersetzen verwenden, können Sie alle geerbte Methoden.

Methode, um eine Liste der Objekte zu erhalten, um die Parameter dieser Methoden zeigen den Typ der Ausnahme-Typen und Arten Rückgabewert nicht schwer.Diese Art der Grundtyp oder Klassentyp sind, kann die Klasse von Objekten der angegebenen Reihenfolge zu beschreiben.

Der Ausgang ist wie folgt:
name = f1

decl class = Klasse method1

param # 0 Klasse java.lang.Object

param int # 1

exc # 0 Klasse java.lang.NullPointerException

Rückgabetyp int =

-----
name = Haupt-

decl class = Klasse method1

param # 0 Klasse [Ljava.lang.String;

Rückgabetyp void =


4. Holen Sie sich Informationen Konstruktor

Klasse Konstruktor für die Verwendung der oben für die Verwendung von ähnlichen Methoden, wie zB:
Import java.lang.reflect .*;

public class constructor1 {
öffentlichen constructor1 () {
}

geschützt constructor1 (int i, double d) {
}

public static void main (String args []) {
try {
Klasse cls = Class.forName ("constructor1");
Constructor ctorlist [] = cls.getDeclaredConstructors ();
for (int i = 0; i ctorlist.length; i + +) {
Constructor ct = ctorlist [i];
System.out.println ("name =" + ct.getName ());
System.out.println ("decl class =" + ct.getDeclaringClass ());
Klasse pVEC [] = ct.getParameterTypes ();
for (int j = 0; j pvec.length; j + +)
System.out.println ("param #" + j + "" + pVEC [j]);
Klasse EVEC [] = ct.getExceptionTypes ();
for (int j = 0; j evec.length; j + +)
System.out.println ("exc #" + j + "" + EVEC [j]);
System.out.println ("-----");
}
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Dieser Fall nicht wieder die Art der Informationen, ist es, weil der Konstruktor nicht zurückgibt Typ.

Das Ergebnis der Ausführung:
name = constructor1

decl class = Klasse constructor1

-----
name = constructor1

decl class = Klasse constructor1

param int # 0

param # 1 Doppel-


5. Für die Klasse Bereich (Domain)

Suchen Sie eine Klasse definiert, welche Daten Felder sind ebenfalls möglich, den folgenden Code in das trockene dieser Sache:
Import java.lang.reflect .*;

public class {Feld1
private double d;
public static final int i = 37;
String s = "Test";

public static void main (String args []) {
try {
Klasse cls = Class.forName ("Feld1");
Field FieldList [] = cls.getDeclaredFields ();
for (int i = 0; i fieldlist.length; i + +) {
Field fld = FieldList [i];
System.out.println ("name =" + fld.getName ());
System.out.println ("decl class =" + fld.getDeclaringClass ());
System.out.println ("type =" + fld.getType ());
int mod = fld.getModifiers ();
System.out.println ("Modifier =" + Modifier.toString (mod));
System.out.println ("-----");
}
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Dieses Beispiel und ist sehr ähnlich wie das vorherige Beispiel.Beispielsweise verwendet ein neues Ding Modifier ist es auch eine Reflexion Klasse, die Mitglieder der Modifikator verwendet, um das Feld zu beschreiben, wie "private int".Diese Modifizierer beschrieben durch die Zahl selbst, und die Verwendung Modifier.toString auf die "offizielle" Beschreibung des Auftrages des Strings (wie "statisch" in die "finale" vor) zurück.Ausgabe dieses Programms ist:
name = d

decl class = Klasse Feld1

type = Doppelzimmer

Modifikatoren = privat

-----
name = i

decl class = Klasse Feld1

type = int

Modifikatoren = public static final

-----
name = s

decl class = Klasse Feld1

type = Klasse java.lang.String

Modifikatoren =

Die Situation und nach Wegen suchen, um das Feld zu bekommen kann nur erreicht werden, wenn die Klasse in den aktuellen Zustand des Feldes Informationen (getDeclaredFields), oder können Sie der übergeordneten Klasse definiert die Felder (getFields) sein.


6. Gemäß dem Verfahren Name der Methode

Text hier, ohne Ausnahme, alle Beispiele und wie erhalten Informationen über die Klasse.Wir können auch Reflexion auf einige andere Dinge, wie die Umsetzung Methode zur Angabe eines Namens zu tun.Das folgende Beispiel demonstriert die folgenden:
Import java.lang.reflect .*;
public class method2 {
public int add (int a, int b) {
Rückkehr a + b;
}
public static void main (String args []) {
try {
Klasse cls = Class.forName ("method2");
Klasse partypes [] = new Class [2];
partypes [0] = Integer.TYPE;
partypes [1] = Integer.TYPE;
Methode meth = cls.getMethod ("add", partypes);
method2 methobj = new method2 ();
Object ArgListe [] = new Object [2];
ArgListe [0] = new Integer (37);
ArgListe [1] = new Integer (47);
Object retobj = meth.invoke (methobj, ArgListe);
Integer retval = (Integer) retobj;
System.out.println (retval.intValue ());
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Wenn ein Programm irgendwo in der Ausführung, wenn es sich der Notwendigkeit bewusst, ein Verfahren durchzuführen ist, diese Methode den Namen des Programms wird in der angegebenen läuft (zum Beispiel, würde JavaBean Entwicklungsumgebung so etwas tun), dann das obige Programmzeigt, wie Sie es tun.

Das obige Beispiel, getMethod verwendet, um zwei Integer-Parameter zu finden und eine Methode namens hinzuzufügen.Finden Sie die Methode, und erstellen Sie die entsprechende Methode Objekt, das Objekt beispielsweise in das Recht, sie auszuführen.Die Umsetzung der Methode, die Notwendigkeit, eine Liste der Parameter, die in dem obigen Beispiel ist ein Integer bzw. Wraps 37 und 47 von zwei Integer-Objekte.Execution-Methode ist eine Integer zurück das gleiche Objekt, das den Rückgabewert von 84 kapselt.


7. Zum Erstellen eines neuen Objekts

Für den Konstrukteur, müssen Sie nicht wie die Umsetzung von Methoden, weil es bedeutet, die Umsetzung eines Konstruktor erstellt ein neues Objekt (um genau zu sein, den Prozess der Erstellung eines Objekts, einschließlich der Zuweisung von Speicher und konstruieren ein Objekt.)Also, mit den meisten ähnliches Beispiel aus dem vorangegangenen Beispiel wie folgt:
Import java.lang.reflect .*;

public class constructor2 {
öffentlichen constructor2 () {
}

öffentlichen constructor2 (int a, int b) {
System.out.println ("a =" + a + "b =" + b);
}

public static void main (String args []) {
try {
Klasse cls = Class.forName ("constructor2");
Klasse partypes [] = new Class [2];
partypes [0] = Integer.TYPE;
partypes [1] = Integer.TYPE;
Constructor ct = cls.getConstructor (partypes);
Object ArgListe [] = new Object [2];
ArgListe [0] = new Integer (37);
ArgListe [1] = new Integer (47);
Object retobj = ct.newInstance (ArgListe);
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Nach der angegebenen Parameter-Typ auf der Suche nach den entsprechenden Konstruktor und führen Sie es zu einem neuen Objekt-Instanz zu erstellen.Diese Methode kann zur Laufzeit verwendet werden, um dynamisch das Objekt erstellen, anstatt Objekte erstellen bei der Kompilierung, die sehr wertvoll ist.


8. Ändern Sie die (Feld-) Wert

Es gibt auch eine nützliche Reflexion des Objekts auf den Wert Datenfeld ändern.Reflexion von einem laufenden Programm auf Objekte nach Namen zu suchen auf dem Feld und ändern Sie es, das folgende Beispiel an diesen Punkt zu illustrieren:
Import java.lang.reflect .*;

public class {Feld2
public double d;

public static void main (String args []) {
try {
Klasse cls = Class.forName ("Feld2");
Field fld = cls.getField ("d");
Feld2 f2obj = new Feld2 ();
System.out.println ("d =" + f2obj.d);
fld.setDouble (f2obj, 12.34);
System.out.println ("d =" + f2obj.d);
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Dies ist beispielsweise der Wert des Feldes durch veränderte d 12.34.


9. Arrays verwenden

Dieser Artikel beschreibt die Reflexion der letzten Operation ist es, eine Reihe von Einsatz zu schaffen.Array in der Programmiersprache Java ist eine spezielle Klasse Typ, kann ein Array Referenz Objektverweis zugewiesen werden.Sehen Sie sich das folgende Beispiel, um zu sehen, wie die Arbeit des Arrays:
Import java.lang.reflect .*;

public class array1 {
public static void main (String args []) {
try {
Klasse cls = Class.forName ("java.lang.String");
Object arr = Array.newInstance (cls, 10);
Array.set (arr, 5, "das ist ein Test");
String s = (String) Array.get (arr, 5);
System.out.println (s);
} Catch (Throwable e) {
System.out.println (e);
}
}
}

Fälle von 10 Einheiten zu schaffen, ein String-Array der Länge, für die ersten 5 Positionen der String ein Wert zugewiesen, und endlich die Zeichenfolge aus dem Array und ausdrucken.

Der folgende Code stellt ein komplexeres Beispiel:
Import java.lang.reflect .*;

public class array2 {
public static void main (String args []) {
int dimmt [] = new int [] {5, 10, 15};
Object arr = Array.newInstance (Integer.TYPE, dimmt);
Object arrobj = Array.get (arr, 3);
Klasse cls = arrobj.getClass () GetComponentType ().
System.out.println (cls);
arrobj = Array.get (arrobj, 5);
Array.setInt (arrobj, 10, 37);
int arrcast [][][] = (int [][][]) arr;
System.out.println (arrcast [3] [5] [10]);
}
}

Beispiel erzeugt ein 5 x 10 x 15 Integer-Array, und in [3] [5] [10] ein Wert von 37 Elementen zugeordnet.Beachten Sie, dass mehrdimensionale Arrays tatsächlich Arrays von Arrays, zum Beispiel nach dem ersten Array.get ist arrobj 10 x 15 Array.Dann lassen Sie sich eines der Elemente, dh ein Array der Länge 15, und verwenden Array.setInt für seine ersten 10 Elemente des Auftrags.

Beachten Sie, dass beim Erstellen des Array-Typ dynamisch ist, bei der Kompilierung nicht kennt seinen Typ.