Java Výukový program Reflection API s příkladem

⚡ Chytré shrnutí

Java Reflection API analyzuje a upravuje možnosti třídy za běhu, včetně jejích polí, metod a konstruktorů. Tento zdroj vysvětluje balíček java.lang.reflect, klíčové metody třídy java.lang.Class a čtyři příklady, které čtou metadata třídy, proměnné, metody a konstruktoru.

  • 🔍 Definice: Reflexe kontroluje a mění třídy a jejich členy za běhu, a to i ty soukromé.
  • ???? Balíček Reflect: Třídy Field, Method, Constructor a Modifier shromažďují deklarativní informace o členech.
  • ???? ️ Metody třídy: Funkce getName(), getSuperclass(), getInterfaces() a getModifiers() vracejí metadata základní třídy.
  • 🧪 Zpracované příklady: Čtyři programy např.tracmetadata třídy, proměnné, metody a konstruktory.
  • ⚠️ Upozornění: Reflexe může přistupovat k soukromým členům a je pomalejší, takže ji používejte jako poslední možnost.

Java Výukový program pro reflexní API

V čem je Reflection in Java?

Java Reflexe je proces analýzy a úpravy všech možností třídy za běhu. Reflexní API v Java se používá k manipulaci s třídou a jejími členy, mezi které patří pole, metody, konstruktory atd., za běhu.

Jednou z výhod rozhraní Reflection API je Java je, že může manipulovat i se soukromými členy třídy.

Balíček java.lang.reflect poskytuje mnoho tříd pro implementaci reflexe. Metody třídy java.lang.Class se používají ke shromažďování kompletních metadat dané třídy.

Třída v balíčku java.lang.reflect

Následuje seznam různý Java třídy v balíčku java.lang.reflect pro implementaci reflexe:

  • Pole: Tato třída se používá ke shromažďování deklarativních informací, jako je datový typ, modifikátor přístupu, název a hodnota proměnné.
  • Metoda: Tato třída se používá ke shromažďování deklarativních informací, jako je modifikátor přístupu, návratový typ, název, typy parametrů a typ výjimky metody.
  • Stavitel: Tato třída se používá ke shromažďování deklarativních informací, jako je modifikátor přístupu, název a typy parametrů konstruktoru.
  • Modifikátor: Tato třída se používá ke shromažďování informací o konkrétním modifikátoru přístupu.

Metody používané v java.lang.Class

  • veřejný řetězec getName(): Vrátí název třídy.
  • veřejná třída getSuperclass(): Vrátí odkaz na nadřazenou třídu.
  • veřejná třída[] getInterfaces(): Vrátí pole rozhraní implementovaných zadanou třídou.
  • public int getModifiers(): Vrací celočíselnou hodnotu představující modifikátory zadané třídy, která musí být předána jako parametr metodě „public static String toString(int i)“, která vrací specifikátor přístupu pro danou třídu.

Jak získat úplné informace o třídě

Chcete-li získat informace o proměnné, metody a konstruktory třídy, musíme vytvořit objekt této třídy. Následující příklad ukazuje různé způsoby, jak vytvořit objekt třídy „Class“:

Metody používané v 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;
    }
}

Příklad 1: Jak získat metadata třídy

Následující příklad ukazuje, jak získat metadata, jako je název třídy, název nadtřídy, implementovaná rozhraní a modifikátory přístupu třídy.

Získáme metadata níže uvedené třídy s názvem Guru99Base.class:

Získejte metadata třídy

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Název třídy je: Guru99Základ
  2. Jeho modifikátory přístupu jsou: public a abstract
  3. Má implementovaná rozhraní: Serializovatelné a klonovatelné
  4. Protože explicitně nerozšířila žádnou třídu, její nadřazená třída je: java.lang.Object

Níže uvedená třída získá metadata Guru99Base.class a vytiskněte jej:

Získejte metadata třídy

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. Vypište název třídy pomocí metody getName().
  2. Vypište název nadřazené třídy pomocí metody getSuperclass().getName().
  3. Vypište názvy implementovaných rozhraní.
  4. Vypište modifikátory přístupu používané třídou.

Získejte metadata třídy

Získejte metadata třídy

Příklad 2: Jak získat metadata proměnné

Následující příklad ukazuje, jak získat metadata proměnné.

Zde vytváříme třídu s názvem Guru99VariableMetaData.class s několika proměnnými:

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

Kroky k získání metadat o proměnných ve výše uvedené třídě:

  1. Vytvořte objekt třídy výše uvedené třídy, tj. Guru99VariableMetaData.class, jak je uvedeno níže:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Získejte metadata ve formě pole Field pomocí metody getFields() or getDeclaredFields() způsoby, jak je uvedeno níže:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

Jedno getFields() Metoda vrací metadata veřejných proměnných ze zadané třídy i z její nadřazené třídy.

Jedno getDeclaredFields() Metoda vrací metadata všech proměnných pouze ze zadané třídy.

  1. Získejte názvy proměnných pomocí metody „public String getName()“.
  2. Získejte datový typ proměnných pomocí metody „public Class getType()“.
  3. Hodnotu proměnné získáme pomocí metody „public xxx get(Field)“. xxx zde může být bajt, short nebo jakýkoli typ hodnoty, kterou chceme načíst.
  4. Získejte modifikátory přístupu proměnných pomocí metod getModifiers() a Modifier.toString(int i).

Zde píšeme třídu pro získání metadat proměnných přítomných ve třídě. Guru99VariableMetaData.class:

Získejte metadata proměnné

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. Vytvořil objekt třídy pro Guru99VariableMetaData.class.
  2. Získáno všechna metadata proměnných v poli Field.
  3. Vytiskl všechny názvy proměnných ve třídě Guru99VariableMetaData.class.
  4. Vypsal všechny datové typy proměnných ve třídě.
  5. Vytiskl všechny modifikátory přístupu proměnných ve třídě.
  6. Vypsal hodnoty všech proměnných ve třídě.

Získejte metadata metody

Získejte metadata metody

Příklad 3: Jak získat metadata metody

Následující příklad ukazuje, jak získat metadata metody.

Zde vytváříme třídu s názvem Guru99MethodMetaData.class s některými metodami:

Získejte metadata metody

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

Kroky k získání metadat o metodách ve výše uvedené třídě:

  1. Vytvořte objekt třídy výše uvedené třídy, tj. Guru99MethodMetaData.class, jak je uvedeno níže:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Získejte informace o metodě v poli metod pomocí metod getMethods() a getDeclaredMethods() dle níže uvedeného postupu:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    Jedno getMethods() Metoda vrací metadata veřejných metod ze zadané třídy i z její nadřazené třídy. getDeclaredMethods() Metoda vrací metadata všech metod pouze ze zadané třídy.

  3. Získejte název metody pomocí getName () metoda.
  4. Získejte návratový typ metody pomocí getReturnType() metoda.
  5. Získejte modifikátory přístupu k metodám pomocí getModifiers() a Modifikátor.toString(int i) metody.
  6. Získejte typy parametrů metody pomocí getParameterTypes() metoda, která vrací pole třídy.
  7. Získejte vyvolání výjimek pomocí getExceptionTypes() metoda, která vrací pole třídy.

Zde píšeme třídu pro získání metadat metod přítomných ve třídě. Guru99MethodMetaData.class:

Získejte metadata metody

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. Vytvořil objekt třídy pro Guru99MethodMetaData.class.
  2. Získáno všechna metadata všech metod v poli Method.
  3. Vypsal všechny názvy metod přítomných ve třídě.
  4. Vytiskl návratové typy metod ve třídě.
  5. Vytiskl všechny modifikátory přístupu metod ve třídě.
  6. Vytiskl typy parametrů metod.
  7. Vypsal výjimky vyvolané metodami.

Získejte metadata metody

Získejte metadata metody

Příklad 4: Jak získat metadata konstruktorů

Následující příklad ukazuje, jak získat metadata konstruktorů.

Zde vytváříme třídu s názvem Guru99Constructor.class s různými konstruktory:

Získejte metadata konstruktorů

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

Zde píšeme třídu pro získání metadat konstruktorů přítomných ve třídě. Guru99Konstruktor.třída:

Získejte metadata konstruktorů

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. Vytvořil objekt třídy pro Guru99Konstruktor.třída.
  2. Získáno všechna metadata všech konstruktorů v poli konstruktorů.
  3. Vytiskla jména všech konstruktérů přítomných ve třídě.
  4. Vytiskly se všechny modifikátory přístupu konstruktorů ve třídě.
  5. Vytiskly se typy parametrů konstruktorů.
  6. Vytiskl výjimky vyvolané konstruktory.

Získejte metadata konstruktorů

Získejte metadata konstruktorů

Nejčastější dotazy

Reflexe umožňuje frameworkům a nástrojům umělé inteligence kontrolovat a vytvářet instance tříd za běhu. Pomáhá vkládání závislostí, serializaci a mapování ORM.pinga dynamické načítání pluginů bez znalosti přesných tříd v době kompilace.

Umělá inteligence dokáže rychle vytvářet reflexní kód, ale měli byste si ho pečlivě prohlédnout. Reflexe může obejít kontroly přístupu a představovat bezpečnostní a výkonnostní rizika, takže vygenerovaný kód je třeba testovat a validovat.

Reflexe je pomalejší než přímá volání metod, může narušit zapouzdření přístupem k soukromým členům a může způsobit problémy se zabezpečením a údržbou. Měla by se používat pouze tehdy, když není k dispozici jednodušší přístup.

Ano. Pomocí setAccessible(true) může reflexe číst a upravovat soukromá pole a volat soukromé metody. To je sice výkonné pro testování a frameworky, ale může to narušit zapouzdření a vytvořit bezpečnostní rizika.

Shrňte tento příspěvek takto: