Java Reflection API Tutorial med exempel

⚡ Smart sammanfattning

Java Reflection API analyserar och modifierar en klass funktioner vid körning, inklusive dess fält, metoder och konstruktorer. Den här resursen förklarar java.lang.reflect-paketet, de viktigaste metoderna i java.lang.Class och fyra exempel som läser metadata för en klass, variabel, metod och konstruktor.

  • 🔍 Definition: Reflektion inspekterar och ändrar klasser och deras medlemmar under körning, även privata klasser.
  • 📦 Reflektera paketet: Klasserna Fält, Metod, Konstruktor och Modifierare samlar in deklarativ information om medlemmar.
  • 🏷️ Klassmetoder: getName(), getSuperclass(), getInterfaces() och getModifiers() returnerar metadata för kärnklassen.
  • 🧪 Arbetade exempel: Fyra program ex.tract-metadata för en klass, variabler, metoder och konstruktorer.
  • ⚠️ Försiktighet: Reflektion kan komma åt privata medlemmar och är långsammare, så använd det som en sista utväg.

Java Handledning för reflektions-API

Vad är reflektion i Java?

Java Reflektion är processen att analysera och modifiera alla funktioner i en klass vid körning. Reflektions-API:et i Java används för att manipulera en klass och dess medlemmar, vilka inkluderar fält, metoder, konstruktorer etc., vid körning.

En fördel med Reflection API i Java är att den också kan manipulera klassens privata medlemmar.

Paketet java.lang.reflect tillhandahåller många klasser för att implementera reflektion. Metoderna i java.lang.Class-klassen används för att samla in fullständiga metadata för en viss klass.

Klass i java.lang.reflect-paketet

Följande är en lista över olika Java klasser i java.lang.reflect-paketet för att implementera reflektion:

  • Fält: Den här klassen används för att samla in deklarativ information såsom datatyp, åtkomstmodifierare, namn och värde för en variabel.
  • Metod: Den här klassen används för att samla in deklarativ information såsom åtkomstmodifierare, returtyp, namn, parametertyper och undantagstyp för en metod.
  • Konstruktör: Den här klassen används för att samla in deklarativ information, såsom åtkomstmodifieraren, namnet och parametertyperna för en konstruktor.
  • Modifierare: Den här klassen används för att samla in information om en viss åtkomstmodifierare.

Metoder som används i java.lang.Class

  • public String getName(): Returnerar klassens namn.
  • offentlig klass getSuperclass(): Returnerar superklassreferensen.
  • public Class[] getInterfaces(): Returnerar en array av gränssnitt som implementerats av den angivna klassen.
  • public int getModifiers(): Returnerar ett heltal som representerar modifierarna för den angivna klassen, vilket måste skickas som en parameter till metoden "public static String toString(int i)" som returnerar åtkomstspecifikationen för den givna klassen.

Hur man får fullständig information om en klass

För att få information om variabler, metoder och konstruktorer för en klass, behöver vi skapa ett objekt för klassen. Följande exempel visar olika sätt att skapa ett objekt för klassen "Klass":

Metoder som används i java.lang.Class

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;
    }
}

Exempel 1: Hur man hämtar metadata för klassen

Följande exempel visar hur man hämtar metadata, till exempel klassnamn, superklassnamn, implementerade gränssnitt och åtkomstmodifierare för en klass.

Vi kommer att hämta metadata för klassen nedan med namnet Guru99Base.klass:

Få metadata av klass

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Klassens namn är: Guru99Base
  2. Dess åtkomstmodifierare är: offentlig och abstract
  3. Den har implementerat gränssnitt: Serialiserbar och Klonbar
  4. Eftersom den inte har utökat någon klass explicit, är dess superklass: java.lang.Object

Klassen nedan kommer att hämta metadata för Guru99Base.class och skriv ut den:

Få metadata av klass

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. Skriv ut klassens namn med metoden getName().
  2. Skriv ut namnet på superklassen med metoden getSuperclass().getName().
  3. Skriv ut namnen på de implementerade gränssnitten.
  4. Skriv ut de åtkomstmodifierare som används av klassen.

Få metadata av klass

Få metadata av klass

Exempel 2: Hur man hämtar metadata för variabel

Följande exempel visar hur man hämtar metadata för en variabel.

Här skapar vi en klass som heter Guru99VariableMetaData.klass med några variabler:

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";
}

Steg för att få metadata om variablerna i ovanstående klass:

  1. Skapa klassobjektet för ovanstående klass, dvs. Guru99VariableMetaData.class, enligt nedan:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Hämta metadata i form av en Field-array med hjälp av getFields() or getDeclaredFields() metoder enligt nedan:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

Ocuco-landskapet getFields() Metoden returnerar metadata för de publika variablerna från den angivna klassen såväl som från dess superklass.

Ocuco-landskapet getDeclaredFields() Metoden returnerar endast metadata för alla variabler från den angivna klassen.

  1. Hämta namnet på variablerna med hjälp av metoden "public String getName()".
  2. Hämta datatypen för variablerna med hjälp av metoden "public Class getType()".
  3. Hämta variabelns värde med hjälp av metoden "public xxx get(Field)". Här kan xxx vara en byte, ett short-värde eller vilket annat värde som helst.
  4. Hämta åtkomstmodifierarna för variablerna med hjälp av metoderna getModifiers() och Modifier.toString(int i).

Här skriver vi en klass för att hämta metadata för de variabler som finns i klassen. Guru99VariableMetaData.klass:

Få metadata av variabel

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. Skapade ett klassobjekt för Guru99VariableMetaData.klass.
  2. Hämtade alla metadata för variablerna i en Field-array.
  3. Skriv ut alla variabelnamn i klassen Guru99VariableMetaData.klass.
  4. Skrev ut alla datatyper för variablerna i klassen.
  5. Skrev ut alla åtkomstmodifierare för variablerna i klassen.
  6. Skrev ut värdena för alla variabler i klassen.

Få metadata av metod

Få metadata av metod

Exempel 3: Hur man hämtar metadata för metoden

Följande exempel visar hur man hämtar metadata för en metod.

Här skapar vi en klass som heter Guru99MethodMetaData.class med några metoder:

Få metadata av metod

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");
    }
}

Steg för att hämta metadata om metoderna i klassen ovan:

  1. Skapa klassobjektet för ovanstående klass, dvs. Guru99MethodMetaData.class, enligt nedan:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Hämta metodinformation i en metodarray med hjälp av metoderna getMethods() och getDeclaredMethods() enligt nedan:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    Ocuco-landskapet getMethods() Metoden returnerar metadata för de publika metoderna från den angivna klassen såväl som från dess superklass. getDeclaredMethods() Metoden returnerar endast metadata för alla metoder från den angivna klassen.

  3. Hämta namnet på metoden med hjälp av hämta namn () metod.
  4. Hämta returtypen för metoden med hjälp av getReturnType() metod.
  5. Hämta åtkomstmodifierare för metoderna med hjälp av getModifiers() och Modifierare.tillString(int i) metoder.
  6. Hämta metodparametertyper med hjälp av getParameterTypes() metod, som returnerar en klassarray.
  7. Få utlösta undantag med hjälp av getExceptionTypes() metod, som returnerar en klassarray.

Här skriver vi en klass för att hämta metadata för de metoder som finns i klassen. Guru99MetodMetaData.klass:

Få metadata av metod

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. Skapade ett klassobjekt för Guru99MetodMetaData.klass.
  2. Hämtade all metadata för alla metoder i en metodarray.
  3. Skrev ut alla metodnamn som finns i klassen.
  4. Skrev ut returtyperna för metoderna i klassen.
  5. Skrev ut alla åtkomstmodifierare för metoderna i klassen.
  6. Skrev ut metodernas parametertyper.
  7. Skrev ut undantagen som genererades av metoderna.

Få metadata av metod

Få metadata av metod

Exempel 4: Hur man hämtar metadata för konstruktorer

Följande exempel visar hur man hämtar metadata för konstruktorer.

Här skapar vi en klass som heter Guru99Constructor.class med olika konstruktorer:

Få metadata från konstruktörer

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 { }
}

Här skriver vi en klass för att hämta metadata för konstruktorerna som finns i klassen. Guru99Konstruktör.klass:

Få metadata från konstruktörer

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. Skapade ett klassobjekt för Guru99Konstruktör.klass.
  2. Hämtade all metadata för alla konstruktorer i en konstruktorarray.
  3. Skrev ut alla konstruktörers namn som fanns i klassen.
  4. Skrev ut alla åtkomstmodifierare för konstruktorerna i klassen.
  5. Skrev ut konstruktorernas parametertyper.
  6. Skrev ut undantagen som konstruktörerna genererade.

Få metadata från konstruktörer

Få metadata från konstruktörer

Vanliga frågor

Reflektion låter ramverk och AI-verktyg inspektera och instansiera klasser vid körning. Det driver beroendeinjektion, serialisering och ORM-mappning.ping, och dynamisk inläsning av plugin utan att känna till de exakta klasserna vid kompileringstillfället.

AI kan snabbt bygga upp reflektionskod, men du bör granska den noggrant. Reflektion kan kringgå åtkomstkontroller och introducera säkerhets- och prestandarisker, så den genererade koden behöver testas och valideras.

Reflektion är långsammare än direkta metodanrop, kan bryta inkapslingen genom att komma åt privata medlemmar och kan orsaka säkerhets- och underhållsproblem. Den bör endast användas när ingen enklare metod finns tillgänglig.

Ja. Med setAccessible(true) kan reflektion läsa och modifiera privata fält och anropa privata metoder. Detta är kraftfullt för testning och ramverk men kan förstöra inkapslingen och skapa säkerhetsproblem.

Sammanfatta detta inlägg med: