Мастерство Java Reflection API: Практическое руководство с примерами кода
Что такое Reflection в Java?
Java Reflection — это процесс анализа и модификации всех возможностей класса во время выполнения. Reflection API в Java используется для манипулирования классом и его членами, включающими поля, методы, конструкторы и т.д. во время выполнения.
Одним преимуществом reflection API в Java является то, что он может манипулировать приватными членами класса.
Пакет java.lang.reflect предоставляет многие классы для реализации reflection в Java. Методы класса java.lang.Class используются для сбора полных метаданных определенного класса.
В этом уроке вы узнаете:
- Что такое Reflection
- Классы в пакете java.lang.reflect
- Методы, используемые в java.lang.Class
- Как получить полную информацию о классе
- Пример 1: Как получить метаданные класса
- Пример 2: Как получить метаданные переменной
- Пример 3: Как получить метаданные метода
- Пример 4: Как получить метаданные конструкторов
Классы в пакете java.lang.reflect
Ниже приведен список различных Java-классов в java.lang.package для реализации reflection:
- Field: Этот класс используется для сбора декларативной информации, такой как тип данных, модификатор доступа, имя и значение переменной.
- Method: Этот класс используется для сбора декларативной информации, такой как модификатор доступа, тип возврата, имя, типы параметров и тип исключения метода.
- Constructor: Этот класс используется для сбора декларативной информации, такой как модификатор доступа, имя и типы параметров конструктора.
- Modifier: Этот класс используется для сбора информации о конкретном модификаторе доступа.
Методы, используемые в java.lang.Class
- Public String getName(): Возвращает имя класса.
- public Class getSuperclass(): Возвращает ссылку на суперкласс.
- Public Class[] getInterfaces(): Возвращает массив интерфейсов, реализованных указанным классом.
- Public int getModifiers(): Возвращает целочисленное значение, представляющее модификаторы указанного класса, которое нужно передать в качестве параметра методу public static String toString(int i), возвращающему спецификатор доступа для данного класса.
Как получить полную информацию о классе
Чтобы получить информацию о переменных, методах и конструкторах класса, нам нужно создать объект класса.

public class Guru99ClassObjectCreation {
public static void main (String[] args) throws ClassNotFoundException {
// 1 - Используя метод Class.forName()
Class c1 = Class.forName("Guru99ClassObjectCreation");
// 2 - Используя метод getClass()
Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
Class c2 = guru99Obj.getClass();
// 3 - Используя .class
Class c3 = Guru99ClassObjectCreation.class;
}
}
Пример 1: Как получить метаданные класса
Следующий пример показывает, как получить метаданные, такие как: имя класса, имя суперкласса, реализованные интерфейсы и модификаторы доступа класса.
Мы получим метаданные класса Guru99Base.class:

import java.io.Serializable;
public abstract class Guru99Base implements Serializable,Cloneable {
}
- Имя класса: Guru99Base
- Его модификаторы доступа: public и abstract
- Реализованные интерфейсы: Serializable и Cloneable
- Поскольку он не расширил какой-либо класс явно, его суперкласс: java.lang.Object
Ниже класс получит метаданные Guru99Base.class и выведет их:

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
public static void main (String [] args) throws ClassNotFoundException {
// Создание объекта Class для Guru99Base.class
Class<Guru99Base> guru99ClassObj = Guru99Base.class;
// Вывод имени класса
System.out.println("Name of the class is : " + guru99ClassObj.getName());
// Вывод имени суперкласса
System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());
// Получение списка реализованных интерфейсов в виде массива Class с помощью getInterfaces()
Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();
// Вывод реализованных интерфейсов с помощью foreach цикла
System.out.print("Implemented interfaces are : ");
for (Class guru99class1 : guru99InterfaceList) {
System.out.print(guru99class1.getName() + " ");
}
System.out.println();
// Получение модификаторов доступа через getModifiers() и toString() метода java.lang.reflect.Modifier
int guru99AccessModifier = guru99ClassObj.getModifiers();
// Вывод модификаторов доступа
System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
}
}
- Вывод имени класса с помощью метода getName
- Вывод имени суперкласса с помощью метода getSuperClass().getName()
- Вывод имен реализованных интерфейсов
- Вывод модификаторов доступа, используемых классом


Пример 2: Как получить метаданные переменной
Следующие примеры показывают, как получить метаданные переменной:
Здесь мы создаем класс Guru99VariableMetaData.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";
}
Шаги для получения метаданных о переменных в вышеуказанном классе:
- Создайте объект класса вышеуказанного класса, то есть Guru99VariableMetaData.class как ниже:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- Получите метаданные в виде массива Field с помощью методов getFields() или getDeclaredFields():
Field[] guru99Field1 = guru99ClassObjVar.getFields(); Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();
getFields() возвращает метаданные публичных переменных из указанного класса, а также из его суперкласса.
getDeclaredFields() возвращает метаданные всех переменных только из указанного класса.
- Получите имя переменных с помощью метода "public String getName()".
- Получите тип данных переменных с помощью метода "public Class getType()".
- Получите значение переменной с помощью метода "public xxx get(Field)". Здесь xxx может быть byte, short или любым типом значения, который мы хотим получить.
- Получите модификаторы доступа переменных с помощью getModifier() и Modifier.toString(int i) методов.
Здесь мы пишем класс для получения метаданных переменных, присутствующих в классе Guru99VariableMetaData.class:

package guru;
import java.lang.reflect.Field;
public class Guru99VariableMetaDataTest {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
// Создание объекта Class для Guru99VariableMetaData.class
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
Class guru99ClassObjVar = guru99ClassVar.getClass();
// Получение метаданных всех полей класса Guru99VariableMetaData
Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();
// Вывод имени, типов данных, модификаторов доступа и значений переменных указанного класса
for (Field field : guru99Field1) {
System.out.println("Variable name : " + field.getName());
System.out.println("Datatypes 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();
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
}
}
- Создан объект класса для Guru99VariableMetaData.class
- Получены все метаданные переменных в массиве Field
- Выведены все имена переменных в классе Guru99VariableMetaData.class
- Выведены все типы данных переменных в классе Guru99VariableMetaData.class
- Выведены все модификаторы доступа переменных в классе Guru99VariableMetaData.class
- Выведены значения всех переменных в классе Guru99VariableMetaData.class


Пример 3: Как получить метаданные метода
Следующие примеры показывают, как получить метаданные метода:
Здесь мы создаем класс Guru99MethodMetaData.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");
}
}
Шаги для получения метаданных о методах в вышеуказанном классе:
- Создайте объект класса вышеуказанного класса, то есть Guru99MethodMetaData.class:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- Получите информацию о методах в массиве Method с помощью getMethods() и getDeclaredMethods():
Method[] guru99Method1 = guru99ClassObjVar.getMethods(); Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();
getMethods() возвращает метаданные публичных методов из указанного класса и его суперкласса.
getDeclaredMethods() возвращает метаданные всех методов только из указанного класса.
- Получите имя метода с помощью getName().
- Получите тип возврата метода с помощью getReturnType().
- Получите модификаторы доступа методов с помощью getModifiers() и Modifier.toString(int i).
- Получите типы параметров метода с помощью getParameterTypes(), возвращающего массив Class.
- Получите выбрасываемые исключения с помощью 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) {
// Создание объекта Class для Guru99MethodMetaData.class
Class guru99ClassObj = Guru99MethodMetaData.class;
// Получение метаданных всех методов класса с помощью 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();
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
}
}
}
- Создан объект класса для Guru99MethodMetaData.class
- Получены все метаданные всех методов в массиве Method
- Выведены все имена методов в классе Guru99MethodMetaData.class
- Выведены типы возврата методов в классе Guru99MethodMetaData.class
- Выведены все модификаторы доступа методов в классе Guru99MethodMetaData.class
- Выведены типы параметров методов в Guru99MethodMetaData.class
- Выведены исключения, выбрасываемые методами в Guru99MethodMetaData.class

Пример 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 {
}
}
Здесь мы пишем класс для получения метаданных конструкторов, присутствующих в классе Guru99Constructor.class:

package guru;
import java.lang.reflect.Constructor;
public class Guru99ConstructorMetaDataTest {
public static void main(String[] args) {
// Создание объекта Class для Guru99Constructor.class
Class guru99Class = Guru99Constructor.class;
// Получение информации обо всех конструкторах в массиве Constructor
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.println("Exception thrown by constructors : ");
for (Class class1 : guru99ExceptionList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
System.out.println("*******************************************");
}
}
}
- Создан объект класса для Guru99Constructor.class
- Получены все метаданные всех конструкторов в массиве Constructor
- Выведены все имена конструкторов в классе Guru99Constructor.class
- Выведены все модификаторы доступа конструкторов в классе Guru99Constructor.class
- Выведены типы параметров конструкторов в Guru99Constructor.class
- Выведены исключения, выбрасываемые конструкторами в Guru99Constructor.class


Резюме:
- Reflection программирование в Java помогает в получении и модификации информации о классах и членах класса: переменные, методы, конструкторы.
- Reflection API в Java может быть реализован с использованием классов в пакете java.lang.reflect и методов класса java.lang.Class.
- Некоторые часто используемые методы класса java.lang.Class: getName(), getSuperclass(), getInterfaces(), getModifiers() и т.д.
- Некоторые часто используемые классы в пакете java.lang.reflect: Field, Method, Constructor, Modifier и т.д.
- Reflection API может обращаться к приватным методам и переменным класса, что может быть угрозой безопасности.
- Reflection API — мощная возможность, предоставляемая Java, но она несет накладные расходы: более низкая производительность, уязвимость безопасности, проблемы с разрешениями. Следовательно, reflection API следует рассматривать как последний ресурс для выполнения операции.
java
- Анонимные внутренние классы в Java: определение, синтаксис и практические примеры
- Рефлексия в Java: инспекция классов, методов и полей во время выполнения
- Освоение Java ObjectInputStream: подробное руководство
- Освоение Java ObjectOutputStream: сериализация, методы и практические примеры
- Классы и объекты в C++: практическое руководство с примерами кода
- Абстрактные классы в C#: практическое руководство с примерами кода
- Понимание String.charAt() в Java: синтаксис, возвращаемый тип, исключения и пример
- Освоение String.endsWith() в Java: проверка суффиксов строки с примерами
- Чтение файлов в Java с BufferedReader — Практическое руководство с примерами
- Алгоритм сортировки вставками в Java: понятный пример и пошаговое руководство