Java Vodič za Reflection API s primjerom

⚡ Pametni sažetak

Java Reflection API analizira i mijenja mogućnosti klase tijekom izvođenja, uključujući njezina polja, metode i konstruktore. Ovaj resurs objašnjava paket java.lang.reflect, ključne metode java.lang.Class i četiri primjera koji čitaju metapodatke klase, varijable, metode i konstruktora.

  • 🔍 Definicija: Refleksija pregledava i mijenja klase i njihove članove tijekom izvođenja, čak i one privatne.
  • ???? Paket Reflekt: Klase Field, Method, Constructor i Modifier prikupljaju deklarativne informacije o članovima.
  • 🏷️ Metode klase: getName(), getSuperclass(), getInterfaces() i getModifiers() vraćaju metapodatke osnovne klase.
  • 🧪 Obrađeni primjeri: Četiri programa extracmetapodaci klase, varijable, metode i konstruktori.
  • ⚠️ Oprez: Refleksija može pristupiti privatnim članovima i sporija je, stoga je koristite kao krajnje rješenje.

Java Vodič za API za refleksiju

U čemu je Reflection Java?

Java Refleksija je proces analiziranja i mijenjanja svih mogućnosti klase za vrijeme izvođenja. Reflection API u Java koristi se za manipuliranje klasom i njezinim članovima, koji uključuju polja, metode, konstruktore itd., tijekom izvođenja.

Jedna od prednosti Reflection API-ja u Java jest da može manipulirati i privatnim članovima klase.

Paket java.lang.reflect pruža mnoge klase za implementaciju refleksije. Metode klase java.lang.Class koriste se za prikupljanje kompletnih metapodataka određene klase.

Klasa u paketu java.lang.reflect

Slijedi popis razne Java Nastava u paketu java.lang.reflect za implementaciju refleksije:

  • Polje: Ova klasa se koristi za prikupljanje deklarativnih informacija kao što su tip podataka, modifikator pristupa, naziv i vrijednost varijable.
  • Metoda: Ova klasa se koristi za prikupljanje deklarativnih informacija kao što su modifikator pristupa, tip povratne vrijednosti, naziv, tipovi parametara i tip iznimke metode.
  • Konstruktor: Ova klasa se koristi za prikupljanje deklarativnih informacija kao što su modifikator pristupa, naziv i tipovi parametara konstruktora.
  • Modifikator: Ova klasa se koristi za prikupljanje informacija o određenom modifikatoru pristupa.

Metode korištene u java.lang.Class

  • javni niz znakova getName(): Vraća naziv klase.
  • javna klasa getSuperclass(): Vraća referencu nadklase.
  • javna klasa[] getInterfaces(): Vraća niz sučelja implementiranih navedenom klasom.
  • javno cijelo uzimanjeModifikatora(): Vraća cjelobrojnu vrijednost koja predstavlja modifikatore navedene klase, a koju je potrebno proslijediti kao parametar metodi „public static String toString(int i)“ koja vraća specifikator pristupa za danu klasu.

Kako dobiti potpunu informaciju o razredu

Da biste dobili informacije o varijable, metode i konstruktore klase, moramo stvoriti objekt klase. Sljedeći primjer prikazuje različite načine stvaranja objekta klase "Klasa":

Metode korištene u 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;
    }
}

Primjer 1: Kako dobiti metapodatke klase

Sljedeći primjer pokazuje kako dobiti metapodatke kao što su naziv klase, naziv nadklase, implementirana sučelja i modifikatori pristupa klase.

Dobit ćemo metapodatke dolje navedene klase Guru99Base.class:

Dohvati metapodatke klase

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Naziv razreda je: Guru99Baza
  2. Njegovi modifikatori pristupa su: public i abs.tract
  3. Ima implementirana sučelja: Serializable i Cloneable
  4. Budući da nije eksplicitno proširila nijednu klasu, njena nadklasa je: java.lang.Object

Donja klasa će dobiti metapodatke od Guru99Base.class i ispišite ga:

Dohvati metapodatke klase

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. Ispišite ime klase koristeći metodu getName().
  2. Ispišite ime nadklase pomoću metode getSuperclass().getName().
  3. Ispišite imena implementiranih sučelja.
  4. Ispišite modifikatore pristupa koje koristi klasa.

Dohvati metapodatke klase

Dohvati metapodatke klase

Primjer 2: Kako dobiti metapodatke varijable

Sljedeći primjer pokazuje kako dobiti metapodatke varijable.

Ovdje stvaramo klasu pod nazivom Guru99VariableMetaData.class s nekim varijablama:

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

Koraci za dobivanje metapodataka o varijablama u gornjoj klasi:

  1. Kreirajte objekt klase gornje klase, tj. Guru99VariableMetaData.class, kao što je prikazano u nastavku:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Dobijte metapodatke u obliku polja polja pomoću getFields() or getDeclaredFields() metode kao u nastavku:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

The getFields() metoda vraća metapodatke javnih varijabli iz navedene klase kao i iz njezine nadklase.

The getDeclaredFields() metoda vraća metapodatke svih varijabli samo iz navedene klase.

  1. Dohvatite naziv varijabli pomoću metode "public String getName()".
  2. Dohvatite tip podataka varijabli pomoću metode "public Class getType()".
  3. Vrijednost varijable dobivamo pomoću metode "public xxx get(Field)". Ovdje xxx može biti bajt, short ili bilo koja vrsta vrijednosti koju želimo dohvatiti.
  4. Dohvatite modifikatore pristupa varijabli pomoću metoda getModifiers() i Modifier.toString(int i).

Ovdje pišemo klasu za dobivanje metapodataka varijabli prisutnih u klasi Guru99VariableMetaData.class:

Dohvati metapodatke varijable

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. Kreiran je objekt klase za Guru99VariableMetaData.class.
  2. Dobio sam sve metapodatke varijabli u nizu polja.
  3. Ispisana su sva imena varijabli u klasi Guru99VariableMetaData.class.
  4. Ispisao je sve tipove podataka varijabli u klasi.
  5. Ispisani su svi modifikatori pristupa varijabli u klasi.
  6. Ispisao je vrijednosti svih varijabli u klasi.

Dohvati metapodatke metode

Dohvati metapodatke metode

Primjer 3: Kako dobiti metapodatke metode

Sljedeći primjer pokazuje kako dobiti metapodatke metode.

Ovdje stvaramo klasu pod nazivom Guru99MethodMetaData.class s nekim metodama:

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

Koraci za dobivanje metapodataka o metodama u gornjoj klasi:

  1. Kreirajte objekt klase gornje klase, tj. Guru99MethodMetaData.class, kao što je prikazano u nastavku:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Dohvatite informacije o metodi u nizu metoda pomoću metoda getMethods() i getDeclaredMethods() kao što je prikazano u nastavku:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    The getMethods() metoda vraća metapodatke javnih metoda iz navedene klase kao i iz njezine nadklase. getDeclaredMethods() metoda vraća metapodatke svih metoda samo iz navedene klase.

  3. Dobijte naziv metode pomoću getName () metoda.
  4. Dobijte povratni tip metode pomoću getReturnType() metoda.
  5. Dobijte modifikatore pristupa metodama pomoću getModifiers() i Modifier.toString(int i) metode.
  6. Dohvatite tipove parametara metode pomoću getParameterTypes() metoda koja vraća niz klase.
  7. Dobijte iznimke korištenjem getExceptionTypes() metoda koja vraća niz klase.

Ovdje pišemo klasu za dobivanje metapodataka metoda prisutnih u klasi. Guru99MethodMetaData.klasa:

Dohvati metapodatke 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. Kreiran je objekt klase za Guru99MethodMetaData.class.
  2. Dobio je sve metapodatke svih metoda u nizu metoda.
  3. Ispisana su sva imena metoda prisutna u klasi.
  4. Ispisao je povratne tipove metoda u klasi.
  5. Ispisani su svi modifikatori pristupa metoda u klasi.
  6. Ispisani su tipovi parametara metoda.
  7. Ispisane su iznimke koje su izbacile metode.

Dohvati metapodatke metode

Dohvati metapodatke metode

Primjer 4: Kako dobiti metapodatke konstruktora

Sljedeći primjer pokazuje kako dobiti metapodatke konstruktora.

Ovdje stvaramo klasu pod nazivom Guru99Constructor.class s različitim konstruktorima:

Dobivanje metapodataka konstruktora

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

Ovdje pišemo klasu za dobivanje metapodataka konstruktora prisutnih u klasi Guru99Konstruktor.klasa:

Dobivanje metapodataka konstruktora

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. Kreiran je objekt klase za Guru99Konstruktor.klasa.
  2. Dobio sam sve metapodatke svih konstruktora u nizu konstruktora.
  3. Ispisana su imena svih konstruktora prisutnih u razredu.
  4. Ispisani su svi modifikatori pristupa konstruktora u klasi.
  5. Ispisani su tipovi parametara konstruktora.
  6. Ispisane su iznimke koje su bacili konstruktori.

Dobivanje metapodataka konstruktora

Dobivanje metapodataka konstruktora

Pitanja i odgovori

Refleksija omogućuje okvirima i AI alatima da pregledavaju i instanciraju klase tijekom izvođenja. Omogućuje ubrizgavanje ovisnosti, serijalizaciju, ORM mapu.ping, i dinamičko učitavanje dodataka bez poznavanja točnih klasa u vrijeme kompajliranja.

Umjetna inteligencija može brzo izraditi refleksijski kod, ali trebali biste ga pažljivo pregledati. Refleksija može zaobići provjere pristupa i uvesti sigurnosne i performansne rizike, pa generirani kod treba testirati i validirati.

Refleksija je sporija od izravnih poziva metoda, može prekinuti enkapsulaciju pristupom privatnim članovima i može uzrokovati probleme sa sigurnošću i održavanjem. Treba je koristiti samo kada nije dostupan jednostavniji pristup.

Da. Korištenjem setAccessible(true), refleksija može čitati i mijenjati privatna polja te pozivati ​​privatne metode. Ovo je moćno za testiranje i okvire, ali može prekinuti enkapsulaciju i stvoriti sigurnosne probleme.

Sažmite ovu objavu uz: