Java Учебное пособие по Reflection API с примером

⚡ Умное резюме

Java API рефлексии анализирует и изменяет возможности класса во время выполнения, включая его поля, методы и конструкторы. В этом ресурсе объясняется пакет java.lang.reflect, основные методы java.lang.Class и приводятся четыре примера чтения метаданных класса, переменной, метода и конструктора.

  • 🔍 Определение: Функция рефлексии проверяет и изменяет классы и их члены во время выполнения, даже приватные.
  • 📦 Пакет Reflect: Классы Field, Method, Constructor и Modifier собирают декларативную информацию о своих членах.
  • 🏷️ Методы класса: Методы getName(), getSuperclass(), getInterfaces() и getModifiers() возвращают метаданные основного класса.
  • 🧪 Рабочие примеры: Четыре программы extracметаданные класса, переменных, методов и конструкторов.
  • ⚠️ Внимание: Reflection имеет доступ к закрытым пользователям и работает медленнее, поэтому используйте его только в крайнем случае.

Java Учебное пособие по API рефлексии

Что такое рефлексия в Java?

Java Рефлексия — это процесс анализа и изменения всех возможностей класса во время выполнения. API рефлексии в Java Используется для управления классом и его членами, включая поля, методы, конструкторы и т. д., во время выполнения.

Одно из преимуществ API рефлексии в Java Дело в том, что оно может манипулировать и закрытыми членами класса.

Пакет java.lang.reflect предоставляет множество классов для реализации рефлексии. Методы класса java.lang.Class используются для сбора полной метаинформации конкретного класса.

Класс в пакете java.lang.reflect

Ниже приведен список различный Java классов в пакете java.lang.reflect для реализации рефлексии:

  • поле: Этот класс используется для сбора декларативной информации, такой как тип данных, модификатор доступа, имя и значение переменной.
  • Метод: Этот класс используется для сбора декларативной информации, такой как модификатор доступа, тип возвращаемого значения, имя, типы параметров и тип исключения метода.
  • Конструктор: Этот класс используется для сбора декларативной информации, такой как модификатор доступа, имя и типы параметров конструктора.
  • Редактировать: Этот класс используется для сбора информации о конкретном модификаторе доступа.

Методы, используемые в java.lang.Class

  • public String getName(): Возвращает название класса.
  • public Class getSuperclass(): Возвращает ссылку на суперкласс.
  • public Class[] getInterfaces(): Возвращает массив интерфейсов, реализованных указанным классом.
  • public int getModifiers(): Возвращает целочисленное значение, представляющее модификаторы указанного класса, которое необходимо передать в качестве параметра методу «public static String toString(int i)», возвращающему спецификатор доступа для заданного класса.

Как получить полную информацию о классе

Чтобы получить информацию о переменныеЧтобы создать объект класса, нам нужно знать, как использовать методы и конструкторы класса. Следующий пример демонстрирует различные способы создания объекта класса «Class»:

Методы, используемые в 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;
    }
}

Пример 1: Как получить метаданные класса

В следующем примере показано, как получить метаданные, такие как имя класса, имя суперкласса, реализованные интерфейсы и модификаторы доступа класса.

Мы получим метаданные класса, указанного ниже. Guru99Base.class:

Получить метаданные класса

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. Название класса: Guru99база
  2. Его модификаторы доступа: public и abstract
  3. Он реализовал интерфейсы: сериализуемый и клонируемый.
  4. Поскольку он явно не наследует ни один класс, его суперклассом является: java.lang.Object.

Приведённый ниже класс получит метаданные Guru99Base.class и распечатайте его:

Получить метаданные класса

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. Выведите название класса с помощью метода getName().
  2. Выведите имя суперкласса, используя метод getSuperclass().getName().
  3. Выведите названия реализованных интерфейсов.
  4. Выведите модификаторы доступа, используемые классом.

Получить метаданные класса

Получить метаданные класса

Пример 2: Как получить метаданные переменной

В следующем примере показано, как получить метаданные переменной.

Здесь мы создаём класс с именем GuruКласс 99VariableMetaData.class содержит несколько переменных:

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

Шаги для получения метаданных о переменных в приведенном выше классе:

  1. Создайте объект класса, соответствующего указанному выше классу, т. е. GuruКласс 99VariableMetaData.class, как показано ниже:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Получите метаданные в виде массива полей, используя... getFields () or getDeclaredFields () методы, как показано ниже:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

getFields () Этот метод возвращает метаданные открытых переменных из указанного класса, а также из его суперкласса.

getDeclaredFields () Этот метод возвращает метаданные всех переменных только из указанного класса.

  1. Получите имена переменных, используя метод «public String getName()».
  2. Получите тип данных переменных, используя метод `public Class getType()`.
  3. Получите значение переменной, используя метод `public xxx get(Field)`. Здесь `xxx` может быть байтом, коротким значением или любым другим типом значения, которое мы хотим получить.
  4. Получите модификаторы доступа к переменным, используя методы getModifiers() и Modifier.toString(int i).

Здесь мы пишем класс для получения метаданных переменных, присутствующих в классе. Guru99VariableMetaData.class:

Получить метаданные переменной

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. Создан объект класса для Guru99VariableMetaData.class.
  2. Получены все метаданные переменных в массиве Field.
  3. Выведены все имена переменных в классе. Guru99VariableMetaData.class.
  4. Выведены все типы данных переменных класса.
  5. Выведены все модификаторы доступа к переменным класса.
  6. Выведены значения всех переменных класса.

Получить метаданные метода

Получить метаданные метода

Пример 3: Как получить метаданные метода

В следующем примере показано, как получить метаданные метода.

Здесь мы создаём класс с именем GuruКласс 99MethodMetaData.class с несколькими методами:

Получить метаданные метода

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

Шаги для получения метаданных о методах в указанном выше классе:

  1. Создайте объект класса, соответствующего указанному выше классу, т. е. GuruКласс 99MethodMetaData.class, как показано ниже:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Получите информацию о методе из массива Method, используя методы getMethods() и getDeclaredMethods(), как показано ниже:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    получитьметоды() Этот метод возвращает метаданные открытых методов указанного класса, а также его суперкласса. getDeclaredMethods () Этот метод возвращает метаданные всех методов только из указанного класса.

  3. Получите название метода, используя GetName () метод.
  4. Получите тип возвращаемого значения метода, используя... получить тип возврата () метод.
  5. Получите модификаторы доступа к методам, используя getModifiers () и Modifier.toString(int i) методы.
  6. Получение типов параметров метода с помощью getParameterTypes () метод, который возвращает массив Class.
  7. Получайте сгенерированные исключения, используя getExceptionTypes() метод, который возвращает массив Class.

Здесь мы пишем класс для получения метаданных методов, присутствующих в этом классе. Guru99MethodMetaData.class:

Получить метаданные метода

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. Создан объект класса для Guru99MethodMetaData.class.
  2. Получены все метаданные всех методов, хранящиеся в массиве Method.
  3. Выведены все имена методов, присутствующие в классе.
  4. Выведены типы возвращаемых значений методов класса.
  5. Выведены все модификаторы доступа методов класса.
  6. Выведены типы параметров методов.
  7. Выведены исключения, сгенерированные методами.

Получить метаданные метода

Получить метаданные метода

Пример 4: Как получить метаданные конструкторов

В следующем примере показано, как получить метаданные конструкторов.

Здесь мы создаём класс с именем Guru99Constructor.class с различными конструкторами:

Получить метаданные конструкторов

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

Здесь мы пишем класс для получения метаданных конструкторов, присутствующих в классе. Guru99Конструктор.класс:

Получить метаданные конструкторов

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. Создан объект класса для Guru99Конструктор.класс.
  2. Получены все метаданные всех конструкторов в массиве Constructor.
  3. Выведены имена всех конструкторов, присутствующих в классе.
  4. Выведены все модификаторы доступа конструкторов класса.
  5. Выведены типы параметров конструкторов.
  6. Выведены исключения, сгенерированные конструкторами.

Получить метаданные конструкторов

Получить метаданные конструкторов

Часто задаваемые вопросы (FAQ)

Рефлексия позволяет фреймворкам и инструментам искусственного интеллекта проверять и создавать экземпляры классов во время выполнения. Она обеспечивает внедрение зависимостей, сериализацию и ORM-карты.pingа также динамическая загрузка плагинов без знания точных классов на этапе компиляции.

Искусственный интеллект может быстро создавать код с использованием рефлексии, но его следует тщательно проверять. Рефлексия может обходить проверки доступа и создавать риски для безопасности и производительности, поэтому сгенерированный код нуждается в тестировании и проверке.

Использование рефлексии медленнее, чем прямые вызовы методов, может нарушить инкапсуляцию при доступе к закрытым членам и может вызвать проблемы с безопасностью и обслуживанием. Её следует использовать только тогда, когда нет более простого подхода.

Да. Используя setAccessible(true), рефлексия может считывать и изменять приватные поля, а также вызывать приватные методы. Это мощный инструмент для тестирования и фреймворков, но может нарушать инкапсуляцию и создавать проблемы с безопасностью.

Подведем итог этой публикации следующим образом: