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: