Java Reflection API Tutorial med eksempel

⚡ Smart opsummering

Java Reflection API analyserer og ændrer en klasses funktioner under kørsel, herunder dens felter, metoder og konstruktører. Denne ressource forklarer java.lang.reflect-pakken, de vigtigste metoder i java.lang.Class og fire eksempler, der læser metadataene for en klasse, variabel, metode og konstruktør.

  • 🔍 Definition: Reflection inspicerer og ændrer klasser og deres medlemmer under kørsel, selv private.
  • 📦 Reflekter pakke: Field-, Method-, Constructor- og Modifier-klasser indsamler deklarativ information om medlemmer.
  • 🏷️ Klassemetoder: getName(), getSuperclass(), getInterfaces() og getModifiers() returnerer metadata for kerneklassen.
  • 🧪 Udarbejdede eksempler: Fire programmer eks.tract metadata for en klasse, variabler, metoder og konstruktører.
  • ⚠️ Forsigtig: Reflektion kan tilgå private medlemmer og er langsommere, så brug det som en sidste udvej.

Java Reflection API-vejledning

Hvad er refleksion i Java?

Java Refleksion er processen med at analysere og ændre alle en klasses funktioner under kørsel. Reflection API'en i Java bruges til at manipulere en klasse og dens medlemmer, herunder felter, metoder, konstruktører osv., under kørsel.

En fordel ved Reflection API'en i Java er, at den også kan manipulere klassens private medlemmer.

Pakken java.lang.reflect tilbyder mange klasser til at implementere refleksion. Metoderne i java.lang.Class-klassen bruges til at indsamle de komplette metadata for en bestemt klasse.

Klasse i java.lang.reflect-pakken

Følgende er en liste over forskellige Java klasser i java.lang.reflect-pakken for at implementere refleksion:

  • Mark: Denne klasse bruges til at indsamle deklarativ information såsom datatype, adgangsmodifikator, navn og værdi af en variabel.
  • Metode: Denne klasse bruges til at indsamle deklarativ information såsom adgangsmodifikator, returtype, navn, parametertyper og undtagelsestype for en metode.
  • Constructor: Denne klasse bruges til at indsamle deklarativ information såsom adgangsmodifikator, navn og parametertyper for en konstruktør.
  • Modifikator: Denne klasse bruges til at indsamle information om en bestemt adgangsmodifikator.

Metoder brugt i java.lang.Class

  • public String getName(): Returnerer klassens navn.
  • offentlig klasse getSuperclass(): Returnerer superklassereferencen.
  • offentlig klasse[] getInterfaces(): Returnerer et array af grænseflader implementeret af den angivne klasse.
  • public int getModifikatorer(): Returnerer en heltalsværdi, der repræsenterer modifikatorerne for den angivne klasse, som skal sendes som en parameter til metoden "public static String toString(int i)", der returnerer adgangsspecifikationen for den givne klasse.

Sådan får du fuldstændig information om en klasse

At få information om variabler, metoder og konstruktører for en klasse, skal vi oprette et objekt for klassen. Følgende eksempel viser forskellige måder at oprette et objekt for klassen "Klasse" på:

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

Eksempel 1: Sådan får du metadata for klassen

Følgende eksempel viser, hvordan man henter metadata, såsom klassenavn, superklassenavn, implementerede grænseflader og adgangsmodifikatorer for en klasse.

Vi får metadataene for nedenstående klasse med navnet Guru99Base.klasse:

Få metadata for klasse

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Klassens navn er: Guru99Base
  2. Dens adgangsmodifikatorer er: offentlig og abstract
  3. Den har implementeret grænseflader: Serialiserbar og Klonbar
  4. Da den ikke har udvidet nogen klasse eksplicit, er dens superklasse: java.lang.Object

Nedenstående klasse vil få metadataene for Guru99Base.class og udskriv den:

Få metadata for klasse

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. Udskriv navnet på klassen ved hjælp af getName()-metoden.
  2. Udskriv navnet på superklassen ved hjælp af metoden getSuperclass().getName().
  3. Udskriv navnene på de implementerede grænseflader.
  4. Udskriv de adgangsmodifikatorer, der bruges af klassen.

Få metadata for klasse

Få metadata for klasse

Eksempel 2: Sådan henter du metadata for en variabel

Følgende eksempel viser, hvordan man henter metadataene for en variabel.

Her opretter vi en klasse med navnet Guru99VariableMetaData.klasse med nogle 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";
}

Trin til at få metadata om variablerne i ovenstående klasse:

  1. Opret klasseobjektet for ovenstående klasse, dvs. Guru99VariableMetaData.klasse, som vist nedenfor:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Hent metadataene i form af et felt-array ved hjælp af getFields() or getDeclaredFields() metoder som nedenfor:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

getFields() Metoden returnerer metadataene for de offentlige variabler fra den angivne klasse såvel som fra dens superklasse.

getDeclaredFields() Metoden returnerer kun metadataene for alle variabler fra den angivne klasse.

  1. Hent navnet på variablerne ved hjælp af metoden "public String getName()".
  2. Hent datatypen for variablerne ved hjælp af metoden "public Class getType()".
  3. Hent værdien af ​​variablen ved hjælp af metoden "public xxx get(Field)". Her kan xxx være en byte, en short eller en hvilken som helst anden type værdi, vi ønsker at hente.
  4. Hent adgangsmodifikatorerne for variablerne ved hjælp af metoderne getModifiers() og Modifier.toString(int i).

Her skriver vi en klasse for at hente metadataene for de variabler, der findes i klassen. Guru99VariableMetaData.klasse:

Få metadata af 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. Oprettede et klasseobjekt til Guru99VariableMetaData.klasse.
  2. Hentede alle metadataene for variablerne i et felt-array.
  3. Udskrev alle variabelnavnene i klassen Guru99VariableMetaData.klasse.
  4. Udskrev alle datatyperne for variablerne i klassen.
  5. Udskrev alle adgangsmodifikatorer for variablerne i klassen.
  6. Udskrev værdierne for alle variablerne i klassen.

Få metadata af metode

Få metadata af metode

Eksempel 3: Sådan henter du metadata for en metode

Følgende eksempel viser, hvordan man henter metadataene for en metode.

Her opretter vi en klasse med navnet Guru99MethodMetaData.klasse med nogle metoder:

Få metadata af metode

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

Trin til at hente metadata om metoderne i ovenstående klasse:

  1. Opret klasseobjektet for ovenstående klasse, dvs. Guru99MethodMetaData.klasse, som vist nedenfor:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Hent metodeoplysninger i et metodearray ved hjælp af metoderne getMethods() og getDeclaredMethods() som vist nedenfor:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    getMethods() Metoden returnerer metadataene for de offentlige metoder fra den angivne klasse såvel som fra dens superklasse. getDeclaredMethods() Metoden returnerer kun metadataene for alle metoder fra den angivne klasse.

  3. Få navnet på metoden ved hjælp af getName () fremgangsmåde.
  4. Hent metodens returtype ved hjælp af getReturnType() fremgangsmåde.
  5. Hent adgangsmodifikatorer for metoderne ved hjælp af getModifiers() og Modifikator.toString(int i) metoder.
  6. Hent metodeparametertyper ved hjælp af getParameterTypes() metode, som returnerer et klasse-array.
  7. Få kastede undtagelser ved hjælp af getExceptionTypes() metode, som returnerer et klasse-array.

Her skriver vi en klasse for at hente metadataene for de metoder, der findes i klassen. Guru99MetodeMetaData.klasse:

Få metadata af metode

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. Oprettede et klasseobjekt til Guru99MetodeMetaData.klasse.
  2. Har fået alle metadataene for alle metoderne i et metodearray.
  3. Udskrev alle metodenavne, der findes i klassen.
  4. Udskrev returtyperne for metoderne i klassen.
  5. Udskrev alle adgangsmodifikatorer for metoderne i klassen.
  6. Udskrev parametertyperne for metoderne.
  7. Udskrev de undtagelser, der blev genereret af metoderne.

Få metadata af metode

Få metadata af metode

Eksempel 4: Sådan henter du metadata fra konstruktører

Følgende eksempel viser, hvordan man henter metadataene for konstruktører.

Her opretter vi en klasse med navnet Guru99Constructor.klasse med forskellige konstruktører:

Få metadata fra 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 { }
}

Her skriver vi en klasse for at hente metadataene for de konstruktører, der er til stede i klassen. Guru99Konstruktør.klasse:

Få metadata fra 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. Oprettede et klasseobjekt til Guru99Konstruktør.klasse.
  2. Har fået alle metadataene for alle konstruktørerne i et konstruktørarray.
  3. Udskrev alle konstruktørernes navne i klassen.
  4. Udskrev alle adgangsmodifikatorer for konstruktørerne i klassen.
  5. Udskrev konstruktørernes parametertyper.
  6. Udskrev de undtagelser, der blev kastet af konstruktørerne.

Få metadata fra konstruktører

Få metadata fra konstruktører

Ofte Stillede Spørgsmål

Reflektion lader frameworks og AI-værktøjer inspicere og instantiere klasser under kørsel. Det understøtter afhængighedsinjektion, serialisering og ORM-kortlægning.ping, og dynamisk plugin-indlæsning uden at kende de nøjagtige klasser på kompileringstidspunktet.

AI kan hurtigt scaffolde refleksionskode, men du bør gennemgå den omhyggeligt. Refleksion kan omgå adgangskontroller og introducere sikkerheds- og ydeevnerisici, så den genererede kode skal testes og valideres.

Refleksion er langsommere end direkte metodekald, kan afbryde indkapslingen ved at tilgå private medlemmer og kan forårsage sikkerheds- og vedligeholdelsesproblemer. Den bør kun bruges, når der ikke findes en enklere tilgang.

Ja. Ved at bruge setAccessible(true) kan refleksion læse og ændre private felter og kalde private metoder. Dette er effektivt til test og frameworks, men kan ødelægge indkapslingen og skabe sikkerhedsproblemer.

Opsummer dette indlæg med: