Heim Java JavaBase So verstehen Sie die Java-Reflexion

So verstehen Sie die Java-Reflexion

Nov 13, 2019 am 10:19 AM
java

So verstehen Sie die Java-Reflexion

Wie versteht man Java-Reflexion?

Übersicht

Java Reflection ist ein Mechanismus, der es uns ermöglicht, interne Informationen von Klassen wie Methoden, Eigenschaften, übergeordneten Klassen, Schnittstellen usw. zu erhalten Laufzeit. Mit anderen Worten: Reflexion ist im Wesentlichen ein „umgekehrter“ Prozess. Wenn wir eine Instanz einer Klasse über new erstellen, wird sie zur Laufzeit tatsächlich von der virtuellen Java-Maschine basierend auf dem Klassenobjekt dieser Klasse erstellt, und die Reflexion erhält ihre Definitionsinformationen über das Klassenobjekt einer Klasse, sodass wir darauf zugreifen können Gehen Sie zu seinen Attributen und Methoden, kennen Sie die übergeordnete Klasse dieser Klasse, welche Schnittstellen implementiert sind und andere Informationen.

Klassenklasse

Wir wissen, dass Javac zum Kompilieren von .java-Dateien in .class-Dateien verwendet werden kann. Diese .class-Datei enthält unsere ursprünglichen Definitionsinformationen der Klasse (. übergeordnete Klassen, Schnittstellen, Konstruktoren, Eigenschaften, Methoden usw.). Die .class-Datei wird zur Laufzeit vom ClassLoader in die Java Virtual Machine (JVM) geladen. Wenn eine .class-Datei geladen wird, generiert die JVM ein Klassenobjekt dafür. Das Objekt, das wir im Programm instanziieren, ist tatsächlich Es wird zur Laufzeit basierend auf dem entsprechenden Klassenobjekt erstellt. Um genau zu sein, ist dieses Class-Objekt tatsächlich eine Instanz der generischen Klasse java.lang.Class> Das Class-Objekt ist beispielsweise eine Class-Instanz. Da die Klasse java.lang.Class 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 nehmen wir die People-Klasse und die Student-Klasse als Beispiele:

public class People {
      private String name;
      private int age;
      public People(String name, int age) {
          this.name = name;
              this.age = age;
      }
      public int getAge() {
          return age;
      } 
      public String getName() {
          return name;
      } 
      public void setAge(int age) {
          this.age = age;
      } 
      public void setName(String name) {
          this.name = name;
      }
      public void speak() {
        System.out.println(getName() + " " + getAge());
     }
}
 
public class Student extends People {
  private int grade;
  public Student(String name, int age) {    
    super(name, age);  
  }
  public Student(String name, int age, int grade) {
    super(name, age);            
    this.grade = grade;  
  }      
  public int getGrade() {   
    return grade;  
  }     
  public void setGrade(int grade) {   
    this.grade = grade;  
  }    
  private void learn(String course) {    
    System.out.println(name + " learn " + course);  
  }
}
Nach dem Login kopieren

Rufen Sie das Klassenobjekt über den Klassennamen ab

Wenn Sie eine Klasse kennen Zum Zeitpunkt der Kompilierung können wir das Klassenobjekt wie folgt abrufen:

Class<People> peopleClass = People.class;
Nach dem Login kopieren

Es gibt auch eine Methode, um das Klassenobjekt basierend auf dem vollständigen Pfadnamen der Klasse wie folgt abzurufen:

//假设People类在com.test包中
Class<People> peopleClass = Class.forName("com.test.People");
Nach dem Login kopieren

Beachten Sie, dass Class.forName() Der Methodenparameter muss der vollständige Pfadname einer Klasse sein. Solange wir „com.test.People“ importieren, können wir sein Klassenobjekt direkt über „People.class“ erhalten, ohne den vollständigen Pfad ausschreiben zu müssen. (Wenn die entsprechende Klasse beim Aufrufen der Class.forName()-Methode nicht im Klassenpfad gefunden wird, wird eine ClassNotFoundException ausgelöst.)

Rufen Sie ihr Klassenobjekt über das Objekt selbst ab

People people = new People("Bill", 18);
Class<People> peopleClass = people.getClass();
Nach dem Login kopieren

Rufen Sie das ab Klasse durch Reflexion Der Konstruktor von

Sobald wir das Klassenobjekt von Menschen erhalten, können wir über dieses Klassenobjekt die ursprünglichen Definitionsinformationen der Menschenklasse erhalten. Lassen Sie uns zunächst das Konstruktorobjekt der People-Klasse abrufen. Mit diesem Konstruktorobjekt können wir ein People-Objekt erstellen. Beispielsweise können wir den folgenden Code zu 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);                 
    people.speak();  
  } catch (Exception e) {  
  } 
}
Nach dem Login kopieren

Oben rufen wir die getConstructor-Methode auf, um ein Konstruktorobjekt der People-Klasse zu erhalten. Da es sich um den formalen Parametertyp des Konstruktors handelt, den wir erhalten möchten ist String und int, also übergeben wir String.class und int.class. Mit dem Konstruktorobjekt können wir die Methode newInstance aufrufen, um ein Personenobjekt zu erstellen.

Beachten Sie, dass Sie nach dem Abrufen der Konstruktor-, Methoden- und Feldobjekte einer Klasse durch Reflektion vor dem Aufrufen der Methoden dieser Objekte zunächst das Accessible-Flag dieses Objekts auf true setzen, um die Java-Sprachzugriffsprüfung abzubrechen. Sie können die Reflexionsgeschwindigkeit erhöhen. Wie im folgenden Code gezeigt:

Constructor<People> constructor = peopleClass.getConstructor(String.class, 
    int.class);
// 设置 constructor 的 Accessible属性为ture以取消Java的访问检查
constructor.setAccessible(true);
Nach dem Login kopieren

Rufen Sie die in der Klasse deklarierten Methoden durch Reflektion ab

Rufen Sie die in der aktuellen Klasse deklarierten Methoden ab (mit Ausnahme derjenigen, die von der übergeordneten Klasse geerbt wurden)

Um alle in der aktuellen Klasse deklarierten Methoden abzurufen, können Sie die Funktion getDeclaredMethods in Class verwenden. Sie ruft alle in der aktuellen Klasse deklarierten Methoden ab (einschließlich privat, öffentlich, statisch usw.) und gibt eine zurück Array von Methodenobjekten, wobei jedes Methodenobjekt eine in einer Klasse deklarierte Methode darstellt. Um die angegebene Methode abzurufen, können Sie getDeclaredMethod(String name, Class... parameterTypes) aufrufen. Wie im folgenden Code gezeigt:

private static void showDeclaredMethods() {  
  Student student = new Student("Bill", 18);   
  //获取Student类声明的所有方法 
  Method[] methods = student.getClass().getDeclaredMethods();       
   try {      
      //获取learnMethod对象(封装了learn方法) 
      Method learnMethod = student.getClass().getDeclaredMethod("learn", 
          String.class);                
      //获取learn方法的参数列表并打印出来 
      Class<?>[] paramClasses = learnMethod.getParameterTypes() ;        
      for (Class<?> class : paramClasses) {      
        System.out.println("learn方法的参数: " + class.getName());    
      }                
      //判断learn方法是否为private 
      System.out.println(learnMethod.getName() + " is private " 
          + Modifier.isPrivate(learnMethod.getModifiers()));   
      //调用learn方法    
      learnMethod.invoke(student, "Java Reflection");  
    } catch (Exception e) {  
  }
}
Nach dem Login kopieren

Rufen Sie die in der aktuellen Klasse und der übergeordneten Klasse deklarierten öffentlichen Methoden ab

Um alle in der aktuellen Klasse und der übergeordneten Klasse deklarierten öffentlichen Methoden abzurufen, müssen Sie Sie können die Funktion getMethods aufrufen. Um eine bestimmte öffentliche Methode zu erhalten, können Sie die Methode getMethod aufrufen. Bitte schauen Sie sich den folgenden Code an:

private static void showMethods() { 
  Student student = new Student("mr.simple");    
  // 获取所有public方法(包括Student本身的和从父类继承来的)  
  Method[] methods = student.getClass().getMethods();   
  try {    
    //注意,通过 getMethod只能获取public方法,若尝试获取private方法则会抛出异常 
    Method learnMethod = student.getClass().getMethod("learn", String.class);
  } catch (Exception e) {  
  }
}
Nach dem Login kopieren

Rufen Sie die in der Klasse definierten Attribute durch Reflektion ab

Das Abrufen von Attributen ähnelt dem Abrufen von Methoden, mit der Ausnahme, dass die Methoden getMethods() / getDeclaredMethods() aufgerufen werden werden ersetzt. Wird zu einem Aufruf der Methode getFields() / getDeclaredFields().

Rufen Sie die in der aktuellen Klasse definierten Attribute ab (mit Ausnahme der von der übergeordneten Klasse geerbten Attribute)

Um alle in der aktuellen Klasse definierten Attribute abzurufen (einschließlich privater, öffentlicher, statischer und anderer Attribute) Sie können die Funktion getDeclaredFields des Klassenobjekts aufrufen. Um die angegebenen Attribute abzurufen, können Sie getDeclaredField aufrufen. Wie im folgenden Code gezeigt:

private static void showDeclaredFields() {   
  Student student = new Student("Bill", 18);    
  // 获取当前类中定义的所有属性  
  Field[] fields = student.getClass().getDeclaredFields();   
  try {    
    // 获取指定的属性 
    Field gradeField = student.getClass().getDeclaredField("grade"); 
    // 获取属性值 
    System.out.println("The grade is : " + gradeField.getInt(student));    
    // 设置属性值    
    gradeField.set(student, 10); 
   } catch (Exception e) { 
  } 
}
Nach dem Login kopieren

Rufen Sie die in der aktuellen Klasse und der übergeordneten Klasse definierten öffentlichen Eigenschaften ab.

So rufen Sie alle in der aktuellen Klasse und der übergeordneten Klasse definierten öffentlichen Eigenschaften ab Sie können die getFields-Funktion des Klassenobjekts aufrufen. Um ein bestimmtes öffentliches Attribut abzurufen, können Sie die getField-Methode aufrufen, wie im folgenden Code gezeigt:

private static void showFields() {  
  Student student = new Student("Bill", 18);            
  // 获取当前类和父类的所有public属性 
  Field[] publicFields = student.getClass().getFields();        
}
Nach dem Login kopieren

Rufen Sie die übergeordnete Klasse der Klasse und die implementierte Schnittstelle ab durch die Klasse durch Reflexion

获取父类

调用Class对象的getSuperClass方法即可,如以下代码所示:

Student student = new Student("Bill", 18);
Class<?> superClass = student.getClass().getSuperclass();
Nach dem Login kopieren

获取所实现的接口

要知道一个类实现了哪些接口,只需调用Class对象的getInterfaces方法,如以下代码所示:

private static void showInterfaces() { 
  Student student = new Student("Bill", 19); 
  Class<?>[] interfaces = student.getClass().getInterfaces();
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonSo verstehen Sie die Java-Reflexion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.

See all articles