Um das Prinzip der Reflexion zu verstehen, müssen Sie zunächst verstehen, welche Art von Informationen sind. Java ermöglicht es uns, die Informationen von Objekten und Klassen zur Laufzeit zu identifizieren, und es gibt zwei Hauptmethoden: Einer ist das traditionelle RTTI, das davon ausgeht, dass wir bereits alle Typinformationen zur Kompilierungszeit kennen. Der andere ist der Reflexionsmechanismus, der es uns ermöglicht, die Informationen von Klassen zur Laufzeit zu entdecken und zu verwenden .
1. Klassenobjekt
Um zu verstehen, wie RTTI in Java funktioniert, müssen Sie zunächst wissen, wie Typinformationen zur Laufzeit dargestellt werden. Dies erfolgt von Klassenobjekten, die Informationen zu Klassen enthält. Klassenobjekte werden verwendet, um alle "regulären" Objekte zu erstellen. Java verwendet Klassenobjekte, um RTTI durchzuführen, auch wenn Sie Vorgänge wie Typ Conversion durchführen.
Jede Klasse generiert ein entsprechendes Klassenobjekt, das in einer .class -Datei gespeichert wird. Alle Klassen werden dynamisch in den JVM geladen, wenn sie zum ersten Mal verwendet werden. Diese Klasse wird geladen, wenn das Programm einen Verweis auf ein statisches Mitglied der Klasse erstellt. Klassenobjekte werden nur bei Bedarf geladen und die statische Initialisierung wird durchgeführt, wenn die Klasse geladen wird.
public class testmain {public static void main (String [] args) {System.out.println (xyz.name);}} Klasse xyz {public static String name = "luoxn28"; konstruiert ");}}Das Ausgangsergebnis ist:
Der Klassenloader prüft zunächst, ob das Klassenobjekt dieser Klasse geladen wurde. Wenn es nicht geladen wurde, sucht der Standardklassenloader die entsprechende .CLASS -Datei basierend auf dem Klassennamen.
Um die Typinformationen zur Laufzeit zu verwenden, müssen Sie einen Verweis auf das Klassenobjekt des Objekts (z. B. ein Basisobjekt) erhalten. Sie können die Funktionsklasse verwenden. Beachten Sie, dass es interessant ist. Wenn die Funktion ".class" verwendet wird, um eine Referenz auf ein Klassenobjekt zu erstellen, wird das Klassenobjekt nicht automatisch initialisiert und verwendet das Klassenobjekt automatisch. Die Vorbereitungen für die Verwendung von Klassen haben im Allgemeinen die folgenden 3 Schritte:
• Laden: Erstellen Sie vom Klassenlader den entsprechenden Bytecode und erstellen Sie ein Klassenobjekt
• Link: Überprüfen Sie den Bytecode in der Klasse und wenden Sie Platz für die statische Domäne zu
• Initialisierung: Wenn die Klasse eine Superklasse hat, wird sie initialisiert und der statische Initialisierer- und statische Initialisierungsblock werden ausgeführt.
öffentliche Klasse Base {static int num = 1; static {System.out.println ("Basis" + num);}} öffentliche Klasse Main {public static void main (String [] args) {// statische Blöcke werden nicht initialisiert klassen clazz1 = base.class; Class.forname ("zzz.base");}} 2. Überprüfen Sie vor der Konvertierung vor dem Typ
Der Compiler prüft, ob der Typ Abwärtsübergang legal ist, und wenn er nicht legal ist, wird eine Ausnahme ausgelöst. Vor dem Umwandeln des Typs können Sie Instanz verwenden, um zu beurteilen.
Klasse Basis {} Klasse abgeleitet erweitert Basis {} public class Main {public static void main (String [] args) {Base Base = new abgeleitet (); if (Base Instance von abgeleitet) {// Hier können Sie down-convert-system.out.println ("OK");} {system.out.println ("nicht ok");}} {}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 3. Reflexion: Laufzeitinformationen
Wenn Sie den genauen Typ eines Objekts nicht kennen, kann es Ihnen RTTI sagen, aber es gibt eine Voraussetzung: Dieser Typ muss zum Kompilierzeit bekannt sein, damit RTTI verwendet werden kann, um ihn zu identifizieren. Die Klassenklasse unterstützt die Reflexion zusammen mit der Klassenbibliothek java.lang.reflect. Diese Klassenbibliothek enthält Feld-, Methoden- und Konstruktorklassen. Die Objekte dieser Klassen werden vom JVM bei Startup erstellt, um die entsprechenden Mitglieder in unbekannten Klassen darzustellen. Auf diese Weise können Sie den Contructor verwenden, um ein neues Objekt zu erstellen, die Methoden GET () und set () zu verwenden, um die mit dem Feldobjekt in der Klasse zugeordneten Felder zu erhalten und zu ändern, und die Methode in ivoke () zum Aufrufen der mit dem Methodenobjekt zugeordneten Methode aufrufen. Darüber hinaus können viele bequeme Methoden wie GetFields (), getMethods () und getConstructors () auch aufgerufen werden, ein Array zurückzugeben, das Felder, Methoden und Konstruktorobjekte darstellt. Auf diese Weise können die Objektinformationen zur Laufzeit vollständig ermittelt werden, ohne etwas über die Klasse zur Kompilierung zu wissen.
Der Reflexionsmechanismus hat nichts Magisches. Wenn der JVM mit einem Objekt eines unbekannten Typs durch Reflexion umgeht, prüft er einfach das Objekt, um zu sehen, zu welcher spezifischen Klasse es gehört. Daher muss die .klasse dieser Klasse für die JVM entweder auf der lokalen Maschine oder aus dem Netzwerk abgeholt werden. Der wahre Unterschied zwischen RTTI und Reflexion ist also nur:
• RTTI, der Compiler öffnet und überprüft. Klassendateien zum Kompilierzeit
• Reflektieren, öffnen und überprüfen Sie die Dateien zur Laufzeit.
public class Person implementiert serialisierbare {private String -Name; privates int Alter; // GET/SET -Methode} public static void main (String [] args) {Person Person = new Person ("luoxn28", 23); Klasse clazz = person.getClass (); Feld [] field.getName (); PropertyDescriptor Descriptor = new PropertyDescriptor (Schlüssel, Clazz); Methode Method = Descriptor.GetReadMethod (); Object Value = methode.invoke (Person); System.out.println (Key + ":" + value);}}} Der obige Aufruf der GET -Funktion der Klasse über die Methode GetReadMethod (), und die Methode getWritemethod () kann verwendet werden, um die festgelegte Methode der Klasse aufzurufen. Im Allgemeinen müssen wir keine Reflexionstools verwenden, aber sie sind nützlicher, um dynamischen Code zu erstellen. Reflexion wird in Java verwendet, um andere Merkmale wie Objektserialisierung und JavaBeans zu unterstützen.
4. Dynamischer Agent
Der Proxy -Modus besteht darin, zusätzliche oder unterschiedliche Operationen bereitzustellen, und die eingefügten Objekte werden verwendet, um "tatsächliche" Objekte zu ersetzen, die die Kommunikation mit "tatsächlichen" Objekten beinhalten, sodass der Proxy normalerweise als Vermittler fungiert. Der dynamische Proxy von Java ist der Idee von Proxy einen Schritt voraus, der dynamisch erstellen und stellvertretende Aufrufe der Proxy -Methoden dynamisch erstellen und verarbeiten kann. Alle auf dem dynamischen Proxy getätigten Anrufe werden in einen einzelnen Anrufprozessor umgeleitet, und seine Aufgabe besteht darin, den Typ des Anrufs anzuzeigen und die entsprechende Richtlinie zu bestimmen. Hier ist ein Beispiel für einen dynamischen Proxy:
Schnittstellen- und Implementierungsklassen:
öffentliche Schnittstelle Schnittstelle {void dosomething (); Dynamischer Proxy -Objektprozessor:
öffentliche Klasse DynamicProxyHandler implementiert InvocationHandler {private Object proxyed; public dynamicproxyHandler (Objekt proxyed) {this.proxyed = proxyed;}@oversidepublic Object Invoke (Object Proxy, Methode Methode, Objekt [] args). Proxy arbeitet. "); return methode.invoke (proxyed, args);}} Testklasse:
public class main {public static void main (String [] args) {RealObject real = new RealObject (); interface proxy = (interface) proxy.newproxyInstance (interface.class.getClassloader (), New Class [] {interface.class}, new New DynamicProxyHandler (real)); proxy.dosomething ();Das Ausgabeergebnis ist wie folgt:
Sie können einen dynamischen Proxy erstellen, indem Sie Proxy statische Methode proxy.newproxyinstance () aufrufen. Diese Methode erfordert einen Klassenlader, eine Liste von Schnittstellen, die der Proxy implementieren soll (keine Klasse oder abstrakte Klasse) und eine Implementierungsklasse von InvocationHandler. Der dynamische Proxy kann alle Aufrufe an den Anrufprozessor umleiten, sodass der Konstruktor des Anrufprozessors normalerweise eine Referenz auf das "tatsächliche" Objekt übergibt, das die Anforderung weiterleitet, wenn der Anrufprozessor die Mediationsaufgabe ausführt.
Das obige ist das eingehende Verständnis der Java-Reflexion, die der Herausgeber Ihnen vorgestellt wurde. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!