1. Einführung
Java Reflection ist ein Mechanismus, mit dem wir interne Informationen von Klassenmethoden, Eigenschaften, übergeordneten Klassen, Schnittstellen usw. zur Laufzeit erhalten können. Mit anderen Worten, Reflexion ist im Wesentlichen ein "umgekehrter" Prozess. Wenn wir eine Instanz einer Klasse durch new erstellen, wird sie tatsächlich von der java -virtuellen Maschine erstellt, die auf Class Klassenobjekt dieser Klasse zur Laufzeit basiert, und es besteht die Reflexion darin, ihre Definitionsinformationen über Class einer Klasse zu erhalten, damit wir auf ihre Eigenschaften und Methoden zugreifen können, die übergeordnete Klasse dieser Klasse und andere Informationen implementiert werden.
2. Klasse
Wir wissen, dass die Verwendung von Javac .java -Dateien in .class -Dateien kompilieren kann, die unsere ursprünglichen Definitionsinformationen für die Klasse (übergeordnete Klasse, Schnittstelle, Konstruktor, Eigenschaften, Methoden usw.) enthalten. Die .class -Datei wird ClassLoader zur Laufzeit in die Java Virtual Machine (JVM) geladen. Wenn eine .class -Datei geladen wird, generiert der JVM ein Klassenobjekt dafür. Die Objekte, die wir im Programm über neue Instanziierung instanziieren, werden tatsächlich basierend auf dem entsprechenden Klassenobjekt zur Laufzeit konstruiert. Um genau zu sein, ist dieses Klassenobjekt tatsächlich eine Instanz java.lang.Class<T> Generic Class. Zum Beispiel ist Class<MyClass> -Objekt eine Class<T> , die die Definitionsinformationen MyClass -Klasse zusammenfasst. Da java.lang.Class<T> keinen öffentlichen Konstruktor hat, können wir diese Klasse nicht direkt instanziieren. Wir können ein Klassenobjekt über die folgende Methode erhalten.
In der folgenden Erklärung werden wir die People -Klasse und die Schülerklasse als Beispiele nutzen:
public class people {private string name; privates int Alter; public people (string name, int ay) {this.name = name; this.age = Alter; } public int getage () {return ay; } public String getName () {return name; } public void setage (int age) {this.age = älter; } public void setName (String -Name) {this.name = name; } public void speak () {System.out.println (getName () + "" + getage ()); }} public Class Student erweitert Menschen {private int grade; public student (String name, int age) {Super (Name, Alter); } public student (String -Name, int Alter, int Klasse) {Super (Name, Alter); this.grade = grade; } public int getGeggrade () {return grade; } public void setgrad (int grade) {this.grade = grade; } private void Learn (String -Kurs) {system.out.println (Name + "Learn" + Kurs); }} Holen Sie sich Klassenobjekt nach Klassenname
Wenn wir den Namen einer Klasse während der Kompilierungsperiode kennen, können wir ihr Klassenobjekt wie folgt erhalten:
Klasse <people> PeopleClass = people.class;
Es gibt auch eine Methode, um Klassenobjekte basierend auf dem vollständigen Pfadnamen der Klasse wie folgt zu erhalten:
// Angenommen, die People -Klasse befindet sich in der com.test -Paketklasse <people> PeopleClass = class.forname ("com.test.people"); Beachten Sie, dass der Parameter Class.forName() der vollständige Pfadname einer Klasse sein muss. Solange wir com.test.people importieren, können wir sein Klassenobjekt direkt über " People.class " erhalten, ohne den vollständigen Pfad aufschreiben zu müssen. (Wenn die entsprechende Klasse im classpath nicht gefunden wird, wenn Class.forName() aufgerufen wird, wird ClassNotFoundException geworfen.)
Holen Sie sich sein Klassenobjekt durch das Objekt selbst
Menschen Menschen = neue Leute ("Bill", 18); Klasse <people> peopleClass = people.getClass (); Holen Sie sich den Konstruktor der Klasse durch Reflexion
Sobald wir das Klassenobjekt von People erhalten haben, können wir die ursprünglichen Definitionsinformationen der People -Klasse über dieses Klassenobjekt erhalten. Lassen Sie uns zunächst das Konstruktorobjekt People -Klasse erhalten. Mit diesem Konstruktorobjekt können wir ein People -Objekt konstruieren. Zum Beispiel können wir den folgenden Code in student.java hinzufügen:
public static void main (String [] args) {class <people> pclass = people.class; try {constructor <people> constructor = pclass.getConstructor (string.class, int.class); People people = constructor.newinstance ("bill", 18); obj.speak (); } catch (Ausnahme e) {}} Im obigen nennen wir getConstructor -Methode, um ein Konstruktorobjekt People -Klasse zu erhalten. Da der Konstruktor die formalen Parameter der Typ String und int erhalten möchte, geben wir in String.class und int.class über. Mit dem Konstruktorobjekt können wir die newInstance -Methode aufrufen, um ein people -Objekt zu erstellen.
Beachten Sie, dass beim Aufrufen der Methoden dieser Objekte, wenn der Constructor , Method und die Field der Klasse durch Reflexion erhalten werden, das accessible Flag dieses Objekts auf true gesetzt wird, um die Überprüfung der Java -Sprachzugriffs -Prüfung zu stornieren, die die Reflexionsgeschwindigkeit verbessern kann. Wie im folgenden Code gezeigt:
Konstruktor <personen> constructor = PeopleClass.getConstructor (string.class, int.class); // Setzen Sie die zugängliche Eigenschaft des Konstruktors so, dass Java Access Check Constructor.
Methoden erhalten, die im Unterricht durch Reflexion deklariert werden
Holen Sie sich die deklarierte Methode in der aktuellen Klasse (ohne von der übergeordneten Klasse geerbt)
Um alle Methoden in der aktuellen Klasse deklarieren zu lassen, können Sie die Funktion getDeclaredMethods in der Klasse verwenden. Alle Methoden werden in der aktuellen Klasse deklariert (einschließlich private , public , static und anderer Methoden). Es wird ein Array von Method zurückgegeben, und jedes Method repräsentiert die in einer Klasse deklarierte Methode. Um die angegebene Methode zu erhalten, können Sie getDeclaredMethod(String name, Class...<T> parameterTypes) aufrufen.
Wie im folgenden Code gezeigt:
private static void showdeclaredMethods () {Student Student = New Student ("Bill", 18); // Alle Methoden erhalten, die von der Schülerklassenmethode deklariert werden [] methodien = student.getClass (). GetDeclaredMethods (); Versuchen Sie {// das LearnMethod -Objekt (verkapselt die Lernmethode) Methode LearnMethod = student.getClass (). getDeclaredMethod ("Learn", String.Class); // Erhalten Sie die Parameterliste der Learn -Methode und drucken Sie die Klasse <?> [] Paramclasses = LearnMethod.getParameterTypes (); für (Klasse <?> Klasse: Paramklassen) {system.out.println ("Methodenparameter:" + class.getName ()); } // Beurteilen Sie, ob die Learn -Methode private system.out.println ist (LearnMethod.getName () + "ist privat" + modifier.issprivate (LearnMethod.getModifierer ())); // Die Learn -Methode LearnMethod.invoke (Student, "Java Reflection") nennen; } catch (Ausnahme e) {}} Lassen Sie öffentliche Methoden in der aktuellen Klasse und in der Elternklasse deklarieren
Um die aktuelle Klasse und alle public Methoden in der übergeordneten Klasse zu erhalten, können Sie die getMethods -Funktion aufrufen und eine bestimmte public Methode erhalten, können Sie die getMethod -Methode aufrufen. Bitte beachten Sie den folgenden Code:
private static void showMethods () {Student Student = New Student ("Mr.simple"); // alle öffentlichen Methoden (einschließlich Schüler selbst und von der Mutterklasse geerbt) Methode [] methods = student.getClass (). GetMethods (); Versuchen Sie {// Beachten Sie, dass nur öffentliche Methoden durch GetMethod erhalten werden können. Wenn Sie versuchen, eine private Methode zu erhalten, wird eine Ausnahme ausgelöst. Methode LearnMethod = student.getClass (). GetMethod ("Learn", String.class); } catch (Ausnahme e) {}} Holen Sie sich die in der Klasse definierten Attribute durch Reflexion
Das Erhalten von Attributen ist ähnlich wie mit Methoden, mit der Ausnahme, dass der Aufruf von getMethods() / getDeclaredMethods() -Methoden durch einen Aufruf an getFields() / getDeclaredFields() -Methoden () ersetzt wird.
Holen Sie sich die in der aktuellen Klasse definierten Attribute (ohne Attribute, die aus der übergeordneten Klasse geerbt wurden)
Um alle Attribute in der aktuellen Klasse definiert zu lassen (einschließlich verschiedener Attribute wie private , public , static usw.), können Sie die Funktion getDeclaredFields des Klassenobjekts aufrufen. Um die angegebenen Attribute zu erhalten, können Sie getDeclaredField aufrufen.
Wie im folgenden Code gezeigt:
private static void showdeclaredfields () {student student = New Student ("Bill", 18); // Alle Attribute in das aktuelle Feld der Klasse definieren [] fields = student.getClass (). GetDeclaredfields (); Versuchen Sie {// Erhalten Sie das angegebene Attribut -Feld addelfield = student.getClass (). getDeclaredfield ("Note"); // das Attributwert system.out.println ("Die Note ist:" + gradefield.getInt (Student)); // Setzen Sie das Attributwert Gradefield.set (Student, 10); } catch (Ausnahme e) {}} Lassen Sie die öffentlichen Attribute in der aktuellen Klasse und der Elternklasse definieren
Um alle public Eigenschaften in der aktuellen Klasse und in der übergeordneten Klasse zu definieren, können Sie die getFields -Funktion Class aufrufen. Um eine bestimmte public Eigenschaft zu erhalten, können Sie getField -Methode aufrufen, wie im folgenden Code gezeigt:
private static void showfields () {Student Student = New Student ("Bill", 18); // Erhalten Sie alle öffentlichen Eigenschaften des aktuellen Feldes für Klasse und Elternklasse [] publicfields = student.getClass (). Getfields (); } Reflexion, um die übergeordnete Klasse der Klasse und die von der Klasse implementierte Schnittstelle zu erhalten
Holen Sie sich die Elternklasse
Rufen Sie einfach die getSuperClass -Methode des Class auf, wie im folgenden Code gezeigt:
Student Student = New Student ("Bill", 18); Klasse <?> SuperClass = Student.getClass (). GetuperClass (); Holen Sie sich die implementierte Schnittstelle
Um zu wissen, welche Schnittstellen eine Klasse implementiert, rufen Sie einfach die getInterfaces -Methode Class auf, wie im folgenden Code gezeigt:
private static void showinterfaces () {student student = New Student ("Bill", 19); Klasse <?> [] Interfaces = student.getClass (). GetInterfaces ();}Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Studium und die Arbeit aller hilfreich sein.