In diesem Artikel werden immer noch kleine Beispiele verwendet, um zu veranschaulichen, da ich immer das Gefühl habe, dass Fallbetrieben das Beste ist. Andernfalls werden Sie nach dem Lesen nicht verstehen, wenn Sie die Theorie nur lesen. Es wird jedoch empfohlen, dass Sie nach dem Lesen des Artikels auf die Theorie zurückblicken und ein besseres Verständnis haben.
Der Haupttext beginnt unten.
[Fall 1] Erhalten Sie das komplette Paket und den Klassennamen über ein Objekt
Paket reflektiert; /*** Erhalten Sie den kompletten Paketnamen und den Klassennamen über ein Objekt***/Klasse Demo {// Andere Codes ...} Klasse Hallo {public static void main (string [] args) {Demo Demo = new Demo (); System.out.println (Demo.getClass (). GetName ()); }}【Auslaufergebnis】: reflektiert.demo
Fügen Sie einen Satz hinzu: Alle Klassenobjekte sind tatsächlich Instanzen der Klasse.
【Fall 2】 Instanziierung des Klassenobjekts
Paket reflektiert; Klasse Demo {// Andere Codes ...} Klasse Hallo {public static void main (string [] args) {class <?> Demo1 = null; Klasse <?> Demo2 = null; Klasse <?> Demo3 = null; Versuchen Sie {// Im Allgemeinen versuchen Sie, dieses Formular zu verwenden. } catch (Ausnahme e) {e.printstacktrace (); } Demo2 = new Demo (). getClass (); Demo3 = Demo.Class; System.out.println ("Klasse name"+Demo1.getName ()); System.out.println ("Klasse name"+Demo2.getName ()); System.out.println ("Klasse name"+Demo3.getName ()); }} 【Betriebsergebnisse】:
Klasse namereFlect.demo
Klasse namereFlect.demo
Klasse namereFlect.demo
[Fall 3] Objekte anderer Klassen durch die Klasse instanziieren
Instanziierte Objekte durch Konstruktion von Nicht-Parametern
öffentliche Person (String -Name, int age) {this.age = älter; this.name = name; }Dann führen Sie das obige Programm weiter aus, und es wird angezeigt:
Wenn Sie also Objekte schreiben, mit denen die Klasse andere Klassen instanziiert, müssen Sie Ihren eigenen Konstruktor ohne Parameter definieren.
[Fall] Rufen Sie Konstruktoren in anderen Klassen über die Klasse auf (Sie können auf diese Weise auch Objekte anderer Klassen durch die Klasse erstellen)
Paket reflektiert; Import Java.lang.reflect.Constructor; Klasse Person {public person () {} public person (String name) {this.name = name; } public Person (int age) {this.age = Alter; } public Person (String -Name, int age) {this.age = älter; this.name = name; } public String getName () {return name; } public int getage () {return ay; } @Override public String toString () {return "["+this.name+""+this.age+"]"; } privater Zeichenfolge Name; privates int Alter; } class Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } Person Per1 = null; Person per2 = null; Person per3 = null; Person per4 = null; // Alle Konstruktoren Konstruktor <?> Cons [] = Demo.getConstructors () erhalten; try {per1 = (Person) cons [0] .Newinstance (); Per2 = (Person) Nachteile [1] .Newinstance ("Rollen"); Per3 = (Person) Nachteile [2] .Newinstance (20); Per4 = (Person) Nachteile [3] .Newinstance ("Rollen", 20); } catch (Ausnahme e) {e.printstacktrace (); } System.out.println (per1); System.out.println (Per2); System.out.println (Per3); System.out.println (Per4); }}【Betriebsergebnisse】:
[NULL 0]
[Rollen 0]
[NULL 20]
[Rollen 20]
【Fall】
Gibt die von einer Klasse implementierte Schnittstelle zurück:
Paket reflektiert; Schnittstelle China {public static Final String name = "Rollen"; öffentliches statisches Int -Alter = 20; öffentliche Void Saychina (); public void Sayshello (String -Name, int Alter); } Klasse Person implementiert China {public Person () {} public Person (String Sex) {this.sex = sex; } public String getSex () {Return Sex; } public void setsex (String sex) {this.sex = sex; } @Override public void saychina () {System.out.println ("Hallo, China"); } @Override public void SayShello (String -Name, int age) {System.out.println (Name+""+Alter); } private String Sex; } class Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } // Alle Schnittstellenklassen <?> Inten [] = Demo.getInterfaces () speichern; für (int i = 0; i <ines.Length; i ++) {System.out.println ("implementierte Schnittstelle"+innes [i] .getName ()); }}}【Betriebsergebnisse】:
Implementierte Schnittstelle reflektiert.china
(Beachten Sie, dass die folgenden Beispiele die Personenklasse dieses Beispiels verwenden. Um Platz zu sparen, werden wir hier nicht mehr den Personen -Code -Teil einfügen, sondern nur den Code der Hauptklasse Hallo))
【Fall】: Holen Sie sich die übergeordnete Klasse in anderen Klassen
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } // Holen Sie sich die übergeordnete Klasse Class <?> Temp = Demo.getSuperClass (); System.out.println ("Die ererbte übergeordnete Klasse ist:"+temp.getName ()); }}【Auslaufergebnisse】
Die ererbte Elternklasse lautet: java.lang.object
【Fall】: Erhalten Sie alle Konstruktoren in anderen Klassen
Dieses Beispiel erfordert das Hinzufügen von Import Java.lang.reflect.* Zu Beginn des Programms;
Schreiben Sie dann die Hauptklasse als:
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } Constructor <?> Cons [] = Demo.getConstructors (); für (int i = 0; i <con.Length; i ++) {System.out.println ("Konstruktor:"+cons [i]); }}}【Betriebsergebnisse】:
Konstruktionsmethode: öffentlich reflektiert.person ()
Konstruktor: Public Reflect.person (Java.lang.String)
Sorgfältige Leser werden jedoch feststellen, dass der obige Konstruktor keine Modifikatoren wie öffentlich oder privat hat
Lassen Sie uns den Modifikator im folgenden Beispiel erhalten
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } Constructor <?> Cons [] = Demo.getConstructors (); für (int i = 0; i <con.Length; i ++) {class <?> p [] = cons [i] .getParameterTypes (); System.out.print ("Konstruktor:"); int mo = cons [i] .getModifierer (); System.out.print (modifier.toString (mo)+""); System.out.print (cons [i] .getName ()); System.out.print ("("); für (int j = 0; j <p.Length; ++ j) {System.out.print (p [j] .getName ()+"arg"+i); if (j <P.Length-1) {System.out.print (",");}} system.println (") {{{{{{{{{{{{{{{}); }}}【Betriebsergebnisse】:
Konstruktor: public reflect.person () {}
Konstruktor: public reflect.person (java.lang.string arg1) {}
Manchmal kann es Ausnahmen in einer Methode geben, haha. Schauen wir uns an:
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } Method -Methode [] = Demo.getMethods (); für (int i = 0; i <method.length; ++ i) {class <?> returnType = methode [i] .getReturnType (); Klasse <?> Para [] = Methode [i] .GetParameterTypes (); int temp = methode [i] .getModifiers (); System.out.print (modifier.toString (temp)+""); System.out.print (returnTyPe.getName ()+""); System.out.print (Methode [i] .getName ()+""); System.out.print ("("); für (int j = 0; j <para.length; ++ j) {System.out.print (para [j] .getName ()+""+"arg"+j); if (j <para.Length-1) {System.out.print (","); if (exce.length> 0) {System.out.print (") löscht"); für (int k = 0; k <exce.length; ++ k) {System.out.print (exce [k] .getName ()+""); if (k <exce.length-1) {System.out.print (","); }}}} else {System.out.print (")"); } System.out.println (); }}} 【Betriebsergebnisse】:[Fall] Als nächstes erhalten wir alle Eigenschaften anderer Klassen. Schließlich werde ich sie zusammen aussortieren, das heißt, den gesamten Rahmen einer Klasse durch die Klasse zu bekommen
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } System.out.println("=========================================================================================== =================================================================ieben =================================================================ieben ============================================================ieben Berechtigungsmodifikator int MO = Field [i] .GetModifiers (); System.out.println("====================================================================================== ==================================================================ieben ==================================================================ieben ==================================================================ieben füleed1 = Demo.getFields (); für (int j = 0; j <fileed1.length; j ++) {// Berechtigungsmodifikator int mo = fehlerhaft [j] .GetModifiers (); String priv = modifier.toString (MO); // Eigenschaftstypklasse <?> Type = fehled1 [j] .Getype (); System.out.println (priv + "" " + type.getName () +" " + fileed1 [j] .getName () +"; "); }}}【Betriebsergebnisse】:
======================================================
Privat Java.lang.String Sex;
==============================================================
Public Static Final Java.lang.String Name;
öffentliches statisches Endalter;
[Fall] Tatsächlich können Methoden in anderen Klassen auch durch Reflexion aufgerufen werden:
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } try {// Die Saychina -Methode in der Personklassenmethode aufrufen = Demo.getMethod ("Saychina"); method.invoke (Demo.Newinstance ()); // Die Sayhello -Methode der Person nennen. method.invoke (Demo.Newinstance (), "Rollen", 20); } catch (Ausnahme e) {e.printstacktrace (); }}}【Betriebsergebnisse】:
Hallo China
Rollen 20
【Fall】 Rufen Sie die Methoden anderer Klassen auf und erhalten Sie Methoden
Klasse Hallo {public static void main (String [] args) {class <?> Demo = null; Objekt obj = null; try {Demo = class.forname ("reflect.person"); } catch (Ausnahme e) {e.printstacktrace (); } try {obj = Demo.Newinstance (); } catch (Ausnahme e) {e.printstacktrace (); } setter (obj, "sex", "männlich", string.class); Getter (obj, "Sex"); } / ** * @param obj * Operation Objekt * @param att * Attribute der Operation * * / public static void getter (Object OBJ, String att) {try {method method = obj.getClass (). getMethod ("get" + att); System.out.println (method.invoke (obj)); } catch (Ausnahme e) {e.printstacktrace (); }} / ** * @param obj * Objekt der Operation * @param att * Attribute der Operation * @param value * Set Value * @param Typ * Attribute des Parameters * * / public static void setter (Objekt obj, String att, Objektwert, Klasse <> type) {try {method method = obj.getClass (). method.invoke (obj, Wert); } catch (Ausnahme e) {e.printstacktrace (); }}} // Endklasse【Betriebsergebnisse】:
männlich
【Fall】 Operation durch Reflexion
Klasse Hallo {public static void main (String [] args) löst eine Ausnahme aus {class <?> Demo = null; Objekt obj = null; Demo = class.Forname ("reflect.person"); obj = Demo.Newinstance (); Field Field = Demo.GetDeclaredfield ("Sex"); field.setAccessible (true); field.set (obj, "männlich"); System.out.println (field.get (obj)); }} // Ende der Klasse[Fall] die Informationen des Arrays durch Reflexion erhalten und ändern:
importieren java.lang.reflect.*; Klasse Hallo {public static void main (String [] args) {int [] temp = {1,2,3,4,5}; Klasse <?> Demo = temp.getClass (). GetComponentType (); System.out.println ("Array Typ:"+Demo.getName ()); System.out.println ("Array Länge"+Array.getLength (temp)); System.out.println ("Erstes Element des Arrays:"+array.get (temp, 0)); Array.set (temp, 0, 100); System.out.println ("Nachdem das erste Element des Arrays geändert wurde ist:"+array.get (temp, 0)); }}【Betriebsergebnisse】:
Array -Typ: int
Arraylänge 5
Das erste Element des Arrays: 1
Nach der Änderung ist das erste Element des Arrays: 100
【Fall】 Ändern Sie die Arraygröße durch Reflexion
Klasse Hallo {public static void main (String [] args) {int [] temp = {1,2,3,4,5,6,7,8,9}; int [] newTemp = (int []) arrayinc (temp, 15); print (newTemp); System.out.println("================================================================================= ===========================================================ieben String []) Arrayinc (ATR, 8); System.ArrayCopy (OBJ, 0, Newarr, co); Array.getLength (obj);【Betriebsergebnisse】:
Die Arraylänge ist: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 ========================================
Die Arraylänge ist: 8
ABC NULL NULL NULL NULL NULL
Dynamischer Agent
[Fall] Schauen wir uns zunächst an, wie Sie den Klassenloader erhalten:
Klasse test {} class Hallo {public static void main (String [] args) {test t = new Test (); System.out.println ("classloader"+t.getClass (). GetClassloader (). GetClass (). GetName ()); }}【Programmausgabe】:
Klasse Loader sun.misc.launcher $ AppClassloader
Tatsächlich gibt es in Java drei Arten von Klassenladern.
1) Bootstrap Classloader Dieser Loader ist in C ++ geschrieben und ist in der allgemeinen Entwicklung selten zu sehen.
2) Der Erweiterungsklassenloader wird verwendet, um erweiterte Klassen zu laden, die im Allgemeinen Klassen im JRE/LIB/EXT -Verzeichnis entsprechen
3) AppClassloader lädt die von ClassPath angegebene Klasse und ist der am häufigsten verwendete Lader. Es ist auch der Standardlader in Java.
Wenn Sie einen dynamischen Proxy absolvieren möchten, müssen Sie zunächst eine Unterklasse der InvocationHandler -Schnittstelle definieren, und der spezifische Betrieb des Proxy wurde abgeschlossen.
Paket reflektiert; importieren java.lang.reflect.*; // Project Interface Interface Subjekt {public String sagt (String -Name, int Age); } // Real Project Class RealSubject implementiert das Thema {@Override public String sagt (String -Name, int age) {return name + "" + älter; }} class myInvocationHandler implementiert invocationHandler {private Object obj = null; öffentliches Objekt Bind (Objekt obj) {this.obj = obj; return proxy.newProxyInstance (obj.getClass (). getClassloader (), obj .getClass (). getInterfaces (), dies); } @Override public Object Invoke (Object Proxy, Methode Methode, Object [] args) wirft Throwable {Object temp = method.invoke (this.obj, args) aus; Temperatur zurückgeben; }} class Hallo {public static void main (String [] args) {myInvocationHandler Demo = new myInvocationHandler (); Subjekt sub = (Subjekt) Demo.bind (new RealSubject ()); String info = sub.say ("Rollen", 20); System.out.println (info); }} 【Betriebsergebnisse】:
Rollen 20
Der Lebenszyklus einer Klasse
Nachdem eine Klasse zusammengestellt wurde, besteht der nächste Schritt darin, die Klasse zu verwenden. Wenn Sie eine Klasse verwenden möchten, ist sie definitiv unzertrennlich von JVM. Während der Programmausführung wird die JVM in diesen drei Schritten abgeschlossen: Laden, Verknüpfung und Initialisierung.
Die Klassenbelastung erfolgt über einen Klassenlader. Der Loader lädt die Binärdatei der .class -Datei in den JVM -Methodenbereich und erstellt ein java.lang.Class -Objekt, das diese Klasse im Haufenbereich beschreibt. Wird verwendet, um Daten zu verkapulieren. Die gleiche Klasse wird jedoch nur vom Klassenlader zuvor geladen
Links sollen binäre Daten in einen Zustand zusammenstellen, der ausgeführt werden kann.
Die Verbindung ist in drei Stufen unterteilt: Überprüfung, Vorbereitung und Parsen
Die Überprüfung wird im Allgemeinen verwendet, um zu bestätigen, ob diese Binärdatei für die aktuelle JVM (Version) geeignet ist.
Die Vorbereitung soll den statischen Mitgliedern Speicherplatz bereitstellen. und Standardwerte festlegen
Parsing bezieht sich auf den Prozess der Konvertierung des Code im konstanten Pool als direkte Referenz, bis alle symbolischen Referenzen vom laufenden Programm verwendet werden können (eine vollständige Korrespondenz festlegen)
Nach Abschluss wird der Typ initialisiert. Nach der Initialisierung kann das Objekt der Klasse normal verwendet werden. Nachdem ein Objekt nicht mehr verwendet wurde, wird es Müll gesammelt. Platz frei machen.
Wenn kein Bezugspunkt auf das Klassenobjekt zeigt, wird es deinstalliert und beendet den Klassenlebenszyklus
Verwenden Sie die Reflexion für den Werksmodus
Schauen wir uns den Werksmodus an, wenn Sie keine Reflexion benötigen:
/ *** @Author Rollen-Holt Factory-Modus des Entwurfsmusters*/ Schnittstelle Frucht {public abstract void eat (); } Klasse Apfel implementiert Frucht {public void eat () {System.out.println ("Apple"); }} Klasse Orange implementiert Frucht {public void eat () {System.out.println ("orange"); }} // Konstruktieren Sie die Fabrikklasse // Mit anderen Worten, wenn wir die Fabrikklasse nur ändern müssen, wenn wir andere Instanzen in der zukünftigen Klassenfabrik hinzufügen {öffentliche statische Frucht GetInstance (String Fruitname) {fruit f = null; if ("apple" .equals (fruitname)) {f = new Apple (); } if ("orange" .equals (fruitname)) {f = new Orange (); } return f; }} Klasse Hallo {public static void main (String [] a) {fruit f = factory.getInstance ("orange"); f.eat (); }} Auf diese Weise müssen wir, wenn wir eine Unterklasse hinzufügen, die Fabrikklasse ändern. Wenn wir zu viele Unterklassen hinzufügen, werden wir uns viel ändern.
Schauen wir uns nun den nutzenden Reflexionsmechanismus an:
Paket reflektiert; Schnittstellenfrucht {public abstrakte void eat (); } Klasse Apfel implementiert Frucht {public void eat () {System.out.println ("Apple"); }} Klasse Orange implementiert Frucht {public void eat () {System.out.println ("orange"); }} class Factory {public statische Frucht GetInstance (String ClassName) {fruit f = null; try {f = (frucht) class.forname (className) .Newinstance (); } catch (Ausnahme e) {e.printstacktrace (); } return f; }} Klasse Hallo {public static void main (String [] a) {fruit f = factory.getInstance ("reflect.apple"); if (f! = null) {f.eat (); }}} Selbst wenn wir so viele Unterklassen hinzufügen, muss die Fabrikklasse nicht geändert werden.
Obwohl die obige Liebe durch Reflexion eine Instanz der Schnittstelle erhalten kann, muss sie im kompletten Paket- und Klassennamen übergeben. Darüber hinaus können Benutzer nicht wissen, wie viele Unterklassen in einer Schnittstelle verwendet werden können. Daher konfigurieren wir die erforderlichen Unterklassen in Form von Attributdateien.
Schauen wir uns an: Factory -Modus kombiniert Attributdateien
Erstellen Sie zuerst eine Ressourcendatei fruit.properties.
Inhalt sind:
Apple = reflektiert.Apple orange = reflect.orange
Schreiben Sie dann den Hauptklassencode:
Paket reflektiert; import Java.io.*; import Java.util.*; Schnittstellenfrucht {public abstrakte void eat (); } Klasse Apfel implementiert Frucht {public void eat () {System.out.println ("Apple"); }} Klasse Orange implementiert Frucht {public void eat () {System.out.println ("orange"); }} // Betriebsdateiklasse init {public statische Eigenschaften getPro () löscht FilenotFoundException, IOException {Properties pro = new Properties () aus; Datei f = neue Datei ("fruit.properties"); if (f.exists ()) {pro.load (neuer FileInputStream (f)); } else {pro.setProperty ("Apple", "Reflect.Apple"); pro.setProperty ("orange", "reflect.orange"); Pro.Store (neuer FileOutputStream (f), "Fruchtklasse"); } return pro; }} class Factory {public statische Frucht GetInstance (String ClassName) {fruit f = null; try {f = (frucht) class.forname (className) .Newinstance (); } catch (Ausnahme e) {e.printstacktrace (); } return f; }} class Hello {public static void main (String [] a) löscht FilenotFoundException, ioException {properties pro = init.getPro () aus; frucht f = factory.getInstance (pro.getProperty ("Apple"); if (f! = null) {f.eat (); }}} 【Laufen Ergebnis】: ApfelDie obige eingehende Analyse der Java-Reflexion (empfohlen) ist der gesamte Inhalt, den ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.