Java Reflection API-Tutorial mit Beispiel

โšก Intelligente Zusammenfassung

Java Die Reflection API analysiert und modifiziert die Eigenschaften einer Klasse zur Laufzeit, einschlieรŸlich ihrer Felder, Methoden und Konstruktoren. Diese Ressource erlรคutert das Paket `java.lang.reflect`, die wichtigsten Methoden von `java.lang.Class` und zeigt anhand von vier Beispielen, wie die Metadaten einer Klasse, einer Variable, einer Methode und eines Konstruktors gelesen werden.

  • ๐Ÿ” Definition: Reflection untersucht und verรคndert Klassen und deren Elemente zur Laufzeit, sogar private.
  • ๐Ÿ“ฆ Reflect-Paket: Feld-, Methoden-, Konstruktor- und Modifikatorklassen sammeln deklarative Informationen รผber ihre Mitglieder.
  • ๐Ÿท๏ธ Klassenmethoden: getName(), getSuperclass(), getInterfaces() und getModifiers() geben Metadaten der Kernklasse zurรผck.
  • ๐Ÿงช Ausgearbeitete Beispiele: Vier Programme extract Metadaten einer Klasse, Variablen, Methoden und Konstruktoren.
  • โš ๏ธ Vorsicht: Reflection kann auf private Mitglieder zugreifen und ist langsamer, daher sollte es nur im รคuรŸersten Notfall verwendet werden.

Java Reflection API Tutorial

Was ist Reflexion in Java?

Java Reflection ist der Prozess der Analyse und Modifizierung aller Fรคhigkeiten einer Klasse zur Laufzeit. Die Reflection-API in Java Wird verwendet, um eine Klasse und ihre Elemente, einschlieรŸlich Felder, Methoden, Konstruktoren usw., zur Laufzeit zu manipulieren.

Ein Vorteil der Reflection API in Java Das Problem ist, dass es auch die privaten Mitglieder der Klasse manipulieren kann.

Das Paket java.lang.reflect stellt zahlreiche Klassen zur Implementierung von Reflection bereit. Die Methoden der Klasse java.lang.Class dienen dazu, die vollstรคndigen Metadaten einer bestimmten Klasse zu erfassen.

Klasse im java.lang.reflect-Paket

Es folgt eine Liste von verschiedene Java Unterricht im java.lang.reflect-Paket zur Implementierung von Reflection:

  • Feld: Diese Klasse dient dazu, deklarative Informationen wie Datentyp, Zugriffsmodifizierer, Name und Wert einer Variablen zu erfassen.
  • Anleitung: Diese Klasse dient dazu, deklarative Informationen wie Zugriffsmodifizierer, Rรผckgabetyp, Name, Parametertypen und Ausnahmetyp einer Methode zu erfassen.
  • Bauherr: Diese Klasse dient dazu, deklarative Informationen wie den Zugriffsmodifizierer, den Namen und die Parametertypen eines Konstruktors zu erfassen.
  • Modifikator: Diese Klasse dient dazu, Informationen รผber einen bestimmten Zugriffsmodifikator zu sammeln.

In java.lang.Class verwendete Methoden

  • public String getName(): Gibt den Namen der Klasse zurรผck.
  • public Class getSuperclass(): Gibt die Referenz auf die Oberklasse zurรผck.
  • public Class[] getInterfaces(): Gibt ein Array von Schnittstellen zurรผck, die von der angegebenen Klasse implementiert werden.
  • public int getModifiers(): Gibt einen ganzzahligen Wert zurรผck, der die Modifikatoren der angegebenen Klasse darstellt und als Parameter an die Methode โ€žpublic static String toString(int i)โ€œ รผbergeben werden muss, welche den Zugriffsspezifizierer fรผr die gegebene Klasse zurรผckgibt.

So erhalten Sie vollstรคndige Informationen zu einer Klasse

Um Informationen zu erhalten VariablenUm die Methoden und Konstruktoren einer Klasse zu verwenden, mรผssen wir ein Objekt dieser Klasse erstellen. Das folgende Beispiel zeigt verschiedene Mรถglichkeiten, ein Objekt der Klasse โ€žClassโ€œ zu erstellen:

In java.lang.Class verwendete Methoden

public class Guru99ClassObjectCreation {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1 - By using Class.forName() method
        Class c1 = Class.forName("Guru99ClassObjectCreation");
        // 2 - By using getClass() method
        Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
        Class c2 = guru99Obj.getClass();
        // 3 - By using .class
        Class c3 = Guru99ClassObjectCreation.class;
    }
}

Beispiel 1: Wie man Metadaten einer Klasse erhรคlt

Das folgende Beispiel zeigt, wie man Metadaten wie den Klassennamen, den Namen der Oberklasse, implementierte Schnittstellen und Zugriffsmodifizierer einer Klasse erhรคlt.

Wir werden die Metadaten der unten stehenden Klasse abrufen, die heiรŸt Guru99Base.class:

Metadaten der Klasse abrufen

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Der Name der Klasse lautet: Guru99Base
  2. Die Zugriffsmodifikatoren sind: รถffentlich und abs.tract
  3. Es verfรผgt รผber implementierte Schnittstellen: Serialisierbar und Klonbar
  4. Da es keine Klasse explizit erweitert hat, ist seine Oberklasse: java.lang.Object

Die folgende Klasse ruft die Metadaten ab. Guru99Base.class und drucke es aus:

Metadaten der Klasse abrufen

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
    public static void main(String[] args) throws ClassNotFoundException {
        // Create Class object for Guru99Base.class
        Class<Guru99Base> guru99ClassObj = Guru99Base.class;

        // Print name of the class
        System.out.println("Name of the class is : " + guru99ClassObj.getName());

        // Print super class name
        System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());

        // Get the list of implemented interfaces using getInterfaces() method
        Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();

        // Print the implemented interfaces using a for-each loop
        System.out.print("Implemented interfaces are : ");
        for (Class guru99class1 : guru99InterfaceList) {
            System.out.print(guru99class1.getName() + " ");
        }
        System.out.println();

        // Get access modifiers using getModifiers() and Modifier.toString()
        int guru99AccessModifier = guru99ClassObj.getModifiers();
        System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
    }
}
  1. Den Namen der Klasse mit der Methode getName() ausgeben.
  2. Den Namen der Oberklasse mit der Methode getSuperclass().getName() ausgeben.
  3. Gib die Namen der implementierten Schnittstellen aus.
  4. Gib die von der Klasse verwendeten Zugriffsmodifizierer aus.

Metadaten der Klasse abrufen

Metadaten der Klasse abrufen

Beispiel 2: Wie man Metadaten einer Variablen erhรคlt

Das folgende Beispiel zeigt, wie man die Metadaten einer Variablen erhรคlt.

Hier erstellen wir eine Klasse namens Guru99VariableMetaData.class mit einigen Variablen:

package guru;
public class Guru99VariableMetaData {
    public static int guru99IntVar1 = 1111;
    static int guru99IntVar2 = 2222;
    static String guru99StringVar1 = "guru99.com";
    static String guru99StringVar2 = "Learning Reflection API";
}

Schritte zum Abrufen der Metadaten zu den Variablen in der obigen Klasse:

  1. Erstellen Sie das Klassenobjekt der oben genannten Klasse, d.h. Guru99VariableMetaData.class, wie unten dargestellt:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Die Metadaten werden mithilfe des folgenden Befehls in Form eines Feld-Arrays abgerufen: getFields() or getDeclaredFields() Methoden wie folgt:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

Das getFields() Die Methode gibt die Metadaten der รถffentlichen Variablen sowohl der angegebenen Klasse als auch ihrer Oberklasse zurรผck.

Das getDeclaredFields() Die Methode gibt nur die Metadaten aller Variablen der angegebenen Klasse zurรผck.

  1. Ermitteln Sie die Namen der Variablen mit der Methode โ€žpublic String getName()โ€œ.
  2. Den Datentyp der Variablen ermitteln Sie mit der Methode โ€žpublic Class getType()โ€œ.
  3. Den Wert der Variablen erhalten Sie mit der Methode โ€žpublic xxx get(Field)โ€œ. Hierbei kann xxx ein Byte, ein Short oder ein beliebiger anderer Datentyp sein, den wir abrufen mรถchten.
  4. Die Zugriffsmodifizierer der Variablen kรถnnen mit den Methoden getModifiers() und Modifier.toString(int i) ermittelt werden.

Hier schreiben wir eine Klasse, um die Metadaten der in der Klasse vorhandenen Variablen zu erhalten. Guru99VariableMetaData.class:

Metadaten der Variablen abrufen

package guru;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Guru99VariableMetaDataTest {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
        // Create Class object for Guru99VariableMetaData.class
        Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
        Class guru99ClassObjVar = guru99ClassVar.getClass();

        // Get the metadata of all the fields of the class
        Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();

        // Print name, data types, access modifiers and values of the variables
        for (Field field : guru99Field1) {
            System.out.println("Variable name : " + field.getName());
            System.out.println("Datatype of the variable : " + field.getType());

            int guru99AccessModifiers = field.getModifiers();
            System.out.println("Access Modifiers of the variable : " + Modifier.toString(guru99AccessModifiers));
            System.out.println("Value of the variable : " + field.get(guru99ClassVar));
            System.out.println();
        }
    }
}
  1. Es wurde ein Klassenobjekt erstellt fรผr Guru99VariableMetaData.class.
  2. Alle Metadaten der Variablen wurden in einem Feld-Array gespeichert.
  3. Alle Variablennamen der Klasse wurden ausgegeben. Guru99VariableMetaData.class.
  4. Alle Datentypen der Variablen in der Klasse wurden ausgegeben.
  5. Alle Zugriffsmodifizierer der Variablen in der Klasse wurden ausgegeben.
  6. Die Werte aller Variablen in der Klasse wurden ausgegeben.

Metadaten der Methode abrufen

Metadaten der Methode abrufen

Beispiel 3: Wie man Metadaten einer Methode erhรคlt

Das folgende Beispiel zeigt, wie man die Metadaten einer Methode erhรคlt.

Hier erstellen wir eine Klasse namens Guru99MethodMetaData.class mit einigen Methoden:

Metadaten der Methode abrufen

package guru;
import java.sql.SQLException;
public class Guru99MethodMetaData {

    public void guru99Add(int firstElement, int secondElement, String result)
    throws ClassNotFoundException, ClassCastException {
        System.out.println("Demo method for Reflection API");
    }
    public String guru99Search(String searchString)
    throws ArithmeticException, InterruptedException {
        System.out.println("Demo method for Reflection API");
        return null;
    }
    public void guru99Delete(String deleteString)
    throws SQLException {
        System.out.println("Demo method for Reflection API");
    }
}

Schritte zum Abrufen der Metadaten zu den Methoden in der obigen Klasse:

  1. Erstellen Sie das Klassenobjekt der oben genannten Klasse, d.h. Guru99MethodMetaData.class, wie unten dargestellt:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Informationen zu Methoden in einem Methoden-Array erhalten Sie mithilfe der Methoden getMethods() und getDeclaredMethods() wie folgt:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    Das getMethods() Die Methode gibt die Metadaten der รถffentlichen Methoden der angegebenen Klasse sowie ihrer Oberklasse zurรผck. getDeclaredMethods() Die Methode gibt nur die Metadaten aller Methoden der angegebenen Klasse zurรผck.

  3. Ermitteln Sie den Namen der Methode mithilfe der getName () Methode.
  4. Ermitteln Sie den Rรผckgabetyp der Methode mithilfe von getReturnType() Methode.
  5. Ermitteln Sie die Zugriffsmodifizierer der Methoden mithilfe der getModifiers() und Modifier.toString(int i) Methoden.
  6. Ermitteln Sie die Methodenparametertypen mithilfe der getParameterTypes() Methode, die ein Klassen-Array zurรผckgibt.
  7. Ausgelรถste Ausnahmen mithilfe der getExceptionTypes() Methode, die ein Klassen-Array zurรผckgibt.

Hier schreiben wir eine Klasse, um die Metadaten der in der Klasse vorhandenen Methoden abzurufen. Guru99MethodMetaData.class:

Metadaten der Methode abrufen

package guru;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Guru99MethodMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99MethodMetaData.class
        Class guru99ClassObj = Guru99MethodMetaData.class;

        // Get the metadata of all the methods using getDeclaredMethods()
        Method[] guru99Methods = guru99ClassObj.getDeclaredMethods();

        for (Method method : guru99Methods) {
            System.out.println("Name of the method : " + method.getName());
            System.out.println("Return type of the method : " + method.getReturnType());

            int guru99ModifierList = method.getModifiers();
            System.out.println("Method access modifiers : " + Modifier.toString(guru99ModifierList));

            Class[] guru99ParamList = method.getParameterTypes();
            System.out.print("Method parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = method.getExceptionTypes();
            System.out.print("Exception thrown by method : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. Es wurde ein Klassenobjekt erstellt fรผr Guru99MethodMetaData.class.
  2. Ich habe alle Metadaten aller Methoden in einem Methoden-Array gespeichert.
  3. Alle in der Klasse vorhandenen Methodennamen wurden ausgegeben.
  4. Die Rรผckgabetypen der Methoden in der Klasse wurden ausgegeben.
  5. Alle Zugriffsmodifizierer der Methoden in der Klasse wurden ausgegeben.
  6. Die Parametertypen der Methoden wurden ausgegeben.
  7. Die von den Methoden ausgelรถsten Ausnahmen wurden ausgegeben.

Metadaten der Methode abrufen

Metadaten der Methode abrufen

Beispiel 4: Wie man Metadaten von Konstruktoren erhรคlt

Das folgende Beispiel zeigt, wie man die Metadaten von Konstruktoren erhรคlt.

Hier erstellen wir eine Klasse namens Guru99Constructor.class mit verschiedenen Konstruktoren:

Holen Sie sich Metadaten von Konstruktoren

package guru;

import java.rmi.RemoteException;
import java.sql.SQLException;

public class Guru99Constructor {

    public Guru99Constructor(int no) throws ClassCastException, ArithmeticException { }
    public Guru99Constructor(int no, String name) throws RemoteException, SQLException { }
    public Guru99Constructor(int no, String name, String address) throws InterruptedException { }
}

Hier schreiben wir eine Klasse, um die Metadaten der in der Klasse vorhandenen Konstruktoren zu erhalten. Guru99Constructor.class:

Holen Sie sich Metadaten von Konstruktoren

package guru;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Guru99ConstructorMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99Constructor.class
        Class guru99Class = Guru99Constructor.class;

        // Get all the constructor information in the Constructor array
        Constructor[] guru99ConstructorList = guru99Class.getConstructors();

        for (Constructor constructor : guru99ConstructorList) {
            System.out.println("Constructor name : " + constructor.getName());

            int guru99Modifiers = constructor.getModifiers();
            System.out.println("Constructor modifier : " + Modifier.toString(guru99Modifiers));

            Class[] guru99ParamList = constructor.getParameterTypes();
            System.out.print("Constructor parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = constructor.getExceptionTypes();
            System.out.print("Exception thrown by constructors : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. Es wurde ein Klassenobjekt erstellt fรผr Guru99Constructor.class.
  2. Ich habe alle Metadaten aller Konstruktoren in einem Konstruktor-Array gespeichert.
  3. Alle in der Klasse vorhandenen Konstruktoren wurden ausgegeben.
  4. Alle Zugriffsmodifizierer der Konstruktoren in der Klasse wurden ausgegeben.
  5. Die Parametertypen der Konstruktoren wurden ausgegeben.
  6. Die von den Konstruktoren ausgelรถsten Ausnahmen wurden ausgegeben.

Holen Sie sich Metadaten von Konstruktoren

Holen Sie sich Metadaten von Konstruktoren

Hรคufig gestellte Fragen

Reflection ermรถglicht es Frameworks und KI-Tools, Klassen zur Laufzeit zu untersuchen und zu instanziieren. Sie ist die Grundlage fรผr Dependency Injection, Serialisierung und ORM-Mapping.pingund das dynamische Laden von Plugins, ohne die genauen Klassen zur Kompilierzeit zu kennen.

KI kann schnell Reflektionscode generieren, dieser sollte jedoch sorgfรคltig geprรผft werden. Reflektion kann Zugriffskontrollen umgehen und Sicherheits- sowie Leistungsrisiken bergen, daher muss der generierte Code getestet und validiert werden.

Reflection ist langsamer als direkte Methodenaufrufe, kann die Kapselung durch den Zugriff auf private Elemente verletzen und Sicherheits- und Wartungsprobleme verursachen. Sie sollte nur dann verwendet werden, wenn keine einfachere Lรถsung verfรผgbar ist.

Ja. Mit `setAccessible(true)` kann Reflection private Felder lesen und รคndern sowie private Methoden aufrufen. Dies ist zwar fรผr Tests und Frameworks sehr nรผtzlich, kann aber die Kapselung verletzen und Sicherheitsrisiken bergen.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: