Java Reflection API oktatóanyag példával

⚡ Okos összefoglaló

Java A Reflection API futásidejű elemzéseket és módosításokat végez egy osztály képességein, beleértve a mezőket, metódusokat és konstruktorokat. Ez az erőforrás ismerteti a java.lang.reflect csomagot, a java.lang.Class főbb metódusait, valamint négy példát, amelyek egy osztály, változó, metódus és konstruktor metaadatait olvassák be.

  • 🔍 Meghatározás: A reflection futásidőben vizsgálja és módosítja az osztályokat és azok tagjait, még a privát osztályokat is.
  • 📦 Reflect csomag: A Field, Method, Constructor és Modifier osztályok deklaratív információkat gyűjtenek a tagokról.
  • 🏷️ Osztálymetódusok: A getName(), getSuperclass(), getInterfaces() és getModifiers() függvények az osztály alapvető metaadatait adják vissza.
  • 🧪 Kidolgozott példák: Négy program pl.tracEgy osztály, változók, metódusok és konstruktorok metaadatai.
  • ⚠️ Figyelem: A reflection hozzáférhet a privát tagokhoz, és lassabb, ezért csak végső megoldásként használjuk.

Java Reflection API oktatóanyag

Miben reflexió Java?

Java A reflexió az osztály összes képességének futásidejű elemzésének és módosításának folyamata. A Reflection API a Java egy osztály és tagjainak futásidejű manipulálására szolgál, amelyek magukban foglalják a mezőket, metódusokat, konstruktorokat stb.

A Reflection API egyik előnye a Java az, hogy az osztály privát tagjait is manipulálhatja.

A java.lang.reflect csomag számos osztályt biztosít a reflektáció megvalósításához. A java.lang.Class osztály metódusai egy adott osztály teljes metaadatainak összegyűjtésére szolgálnak.

Osztály a java.lang.reflect csomagban

Az alábbiakban egy lista található különféle Java osztályok a java.lang.reflect csomagban a reflexió megvalósításához:

  • Mező: Ez az osztály deklaratív információk, például egy változó adattípusának, hozzáférés-módosítójának, nevének és értékének gyűjtésére szolgál.
  • Módszer: Ez az osztály deklaratív információk gyűjtésére szolgál, mint például a metódus hozzáférési módosítója, visszatérési típusa, neve, paramétertípusai és kivételtípusa.
  • építész: Ez az osztály deklaratív információk gyűjtésére szolgál, például a konstruktor hozzáférési módosítójára, nevére és paramétertípusaira.
  • Módosító: Ez az osztály egy adott hozzáférés-módosítóról gyűjt információkat.

A java.lang.Class-ban használt módszerek

  • nyilvános karakterlánc getName(): Visszaadja az osztály nevét.
  • nyilvános osztály getSuperclass(): Visszaadja a szuperosztály referenciáját.
  • nyilvános Osztály[] getInterfaces(): A megadott osztály által megvalósított interfészek tömbjét adja vissza.
  • nyilvános int getModifiers(): Egy egész értéket ad vissza, amely a megadott osztály módosítóit jelöli, és amelyet paraméterként kell átadni a „public static String toString(int i)” metódusnak, amely visszaadja az adott osztály hozzáférési specifikátorát.

Hogyan szerezhet teljes információt egy osztályról

Információt szerezni arról változókEgy osztály , metódusai és konstruktorai esetén létre kell hoznunk az osztály egy objektumát. A következő példa bemutatja az „Osztály” osztályú objektum létrehozásának különböző módjait:

A java.lang.Class-ban használt módszerek

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

1. példa: Hogyan lehet lekérni az osztály metaadatait

A következő példa bemutatja, hogyan lehet metaadatokat lekérni, például egy osztály nevét, a szuperosztály nevét, a megvalósított interfészeket és az osztály hozzáférés-módosítóit.

Megkapjuk az alábbi nevű osztály metaadatait Guru99Base.osztály:

Szerezze be az osztály metaadatait

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Az osztály neve: Guru99 Alap
  2. Hozzáférési módosítói a következők: public és abstract
  3. Megvalósított interfészekkel rendelkezik: Sorosozható és Klónozható
  4. Mivel explicit módon nem terjesztett ki egyetlen osztályt sem, a szuperosztálya: java.lang.Object

Az alábbi osztály a következő metaadatokat fogja megkapni: Guru99Base.class fájlt és írd ki:

Szerezze be az osztály metaadatait

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. Nyomtassa ki az osztály nevét a getName() metódussal.
  2. Nyomtassa ki a szuperosztály nevét a getSuperclass().getName() metódussal.
  3. Nyomtassa ki a megvalósított interfészek nevét.
  4. Nyomtassa ki az osztály által használt hozzáférés-módosítókat.

Szerezze be az osztály metaadatait

Szerezze be az osztály metaadatait

2. példa: Hogyan lehet lekérni egy változó metaadatait

A következő példa bemutatja, hogyan lehet lekérni egy változó metaadatait.

Itt létrehozunk egy osztályt, melynek neve Guru99VariableMetaData.osztály néhány változóval:

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

A fenti osztály változóira vonatkozó metaadatok beszerzésének lépései:

  1. Hozd létre a fenti osztály osztályobjektumát, azaz Guru99VariableMetaData.class, az alábbiak szerint:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. A metaadatokat Field tömb formájában kell lekérni a következő használatával: getFields() or getDeclaredFields() módszerek az alábbiak szerint:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

Az getFields() A metódus visszaadja a megadott osztályból, valamint annak szuperosztályából származó nyilvános változók metaadatait.

Az getDeclaredFields() A metódus csak a megadott osztály összes változójának metaadatait adja vissza.

  1. A változók nevét a „public String getName()” metódussal szerezheted meg.
  2. A változók adattípusát a „public Class getType()” metódussal szerezheted meg.
  3. A változó értékét a „public xxx get(Field)” metódussal szerezheted meg. Itt az xxx lehet egy bájt, egy rövid karakter, vagy bármilyen más típusú érték, amit le szeretnénk kérni.
  4. A változók hozzáférés-módosítóit a getModifiers() és a Modifier.toString(int i) metódusok segítségével szerezheted be.

Itt egy osztályt írunk, amely a benne lévő változók metaadatait kéri le. Guru99VariableMetaData.class:

Változó metaadatainak lekérése

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. Létrehozott egy osztályobjektumot a következőhöz: Guru99VáltozóMetaAdatok.osztály.
  2. Megkapta a változók összes metaadatát egy Field tömbben.
  3. Kiírta az osztály összes változónevét Guru99VáltozóMetaAdatok.osztály.
  4. Kinyomtatta az osztályban lévő változók összes adattípusát.
  5. Kiírta az osztályban lévő változók összes hozzáférési módosítóját.
  6. Kinyomtatta az osztály összes változójának értékét.

Szerezze be a módszer metaadatait

Szerezze be a módszer metaadatait

3. példa: Hogyan lehet lekérni a metódus metaadatait

A következő példa bemutatja, hogyan lehet lekérni egy metódus metaadatait.

Itt létrehozunk egy osztályt, melynek neve Guru99MethodMetaData.osztály néhány metódussal:

Szerezze be a módszer metaadatait

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

A fenti osztály metódusairól szóló metaadatok lekérésének lépései:

  1. Hozd létre a fenti osztály osztályobjektumát, azaz Guru99MethodMetaData.osztály, az alábbiak szerint:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. A getMethods() és getDeclaredMethods() metódusok használatával a Method tömbben található metódusinformációk lekérése az alábbiak szerint:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    Az getMethods() A metódus visszaadja a megadott osztályból, valamint a szuperosztályából származó nyilvános metódusok metaadatait. A getDeclaredMethods() A metódus csak a megadott osztály összes metódusának metaadatait adja vissza.

  3. Szerezd meg a metódus nevét a következő használatával: getName () módszer.
  4. A metódus visszatérési típusát a következővel kapjuk meg: getReturnType() módszer.
  5. A metódusok hozzáférés-módosítóinak lekérése a következő használatával: getModifiers() és a Módosító.String(int i) mód.
  6. Metódusparaméter-típusok lekérése a következő használatával: getParameterTypes() metódus, amely egy Osztály tömböt ad vissza.
  7. Kivételek kiváltása a következő használatával: getExceptionTypes() metódus, amely egy Osztály tömböt ad vissza.

Itt egy osztályt írunk, hogy lekérjük az osztályban jelen lévő metódusok metaadatait. Guru99MethodMetaData.osztály:

Szerezze be a módszer metaadatait

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. Létrehozott egy osztályobjektumot a következőhöz: Guru99MethodMetaData.class.
  2. Megkapta az összes metódus metaadatait egy metódus tömbben.
  3. Kinyomtatta az osztályban előforduló összes metódusnevet.
  4. Kiírta az osztályban lévő metódusok visszatérési típusait.
  5. Kiírta az osztály metódusainak összes hozzáférési módosítóját.
  6. Kiírta a metódusok paramétertípusait.
  7. Kiírta a metódusok által generált kivételeket.

Szerezze be a módszer metaadatait

Szerezze be a módszer metaadatait

4. példa: Hogyan lehet lekérni a konstruktorok metaadatait

A következő példa bemutatja, hogyan lehet lekérni a konstruktorok metaadatait.

Itt létrehozunk egy osztályt, melynek neve Guru99Constructor.osztály különböző konstruktorokkal:

Szerezze be a konstruktorok metaadatait

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

Itt egy osztályt írunk, amely az osztályban jelenlévő konstruktorok metaadatait kéri le. Guru99Konstruktor.osztály:

Szerezze be a konstruktorok metaadatait

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. Létrehozott egy osztályobjektumot a következőhöz: Guru99Konstruktor.osztály.
  2. Megkapta az összes konstruktor metaadatait egy konstruktor tömbben.
  3. Kiírta az osztályban előforduló összes konstruktor nevét.
  4. Kiírta az osztály konstruktorainak összes hozzáférési módosítóját.
  5. Kiírta a konstruktorok paramétertípusait.
  6. Kiírta a konstruktorok által dobott kivételeket.

Szerezze be a konstruktorok metaadatait

Szerezze be a konstruktorok metaadatait

GYIK

A reflection lehetővé teszi a keretrendszerek és a mesterséges intelligencia eszközök számára az osztályok futásidejű vizsgálatát és példányosítását. Használhatóvá teszi a függőségek injektálását, a szerializálást és az ORM-térképezést.ping, és dinamikus bővítmények betöltése anélkül, hogy a fordítási időben ismernénk a pontos osztályokat.

A mesterséges intelligencia gyorsan képes a reflexiós kódot felépíteni, de alaposan át kell tekinteni. A reflexió megkerülheti a hozzáférési ellenőrzéseket, és biztonsági és teljesítménykockázatokat okozhat, ezért a létrehozott kódot tesztelni és validálni kell.

A reflektálás lassabb, mint a közvetlen metódushívások, a privát tagok elérésével felboríthatja a beágyazást, és biztonsági és karbantartási problémákat okozhat. Csak akkor szabad használni, ha nincs egyszerűbb megközelítés.

Igen. A setAccessible(true) használatával a reflection képes privát mezőket olvasni és módosítani, valamint privát metódusokat meghívni. Ez hatékony teszteléshez és keretrendszerekhez, de felboríthatja a beágyazást és biztonsági aggályokat okozhat.

Foglald össze ezt a bejegyzést a következőképpen: