Java Reflection API

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

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

Возможности

Помимо самомодификации, API способен проводить самопроверку и самоклонирование. Чаще всего рефлексию Java используют:

  • для получения информации о классах, интерфейсах, функциях, конструкторах, методах и модулях;
  • изменения имен функций и классов во время выполнения программы;
  • создания новых экземпляров классов;
  • анализа и исполнения кода, поступающего из программного окружения;
  • преобразования классов из одного типа в другой;
  • создания массивов данных и манипуляций с ними;
  • установления значений полей объектов по именам;
  • получения доступа к переменным и методам, включая приватные, и к внешним классам;
  • вызова методов объектов по именам.
Схема работы Reflection API

Особенности рефлексии в Java

Снижение производительности программы

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

Блокировка диспетчером безопасности

Для запуска рефлексии в программировании требуется разрешение на выполнение, которое, как правило, не выдается при работе программного компонента под управлением Security Manager (диспетчера безопасности). 

Уязвимость

При неверном использовании API способен нарушать один из главных принципов объектно-ориентированного программирования — инкапсуляцию данных. Это может привести к появлению потенциальных уязвимостей в веб-приложениях. В период с 2013 по 2016 год в библиотеке Reflection существовала брешь, которая позволяла хакерам обходить «песочницу» (изолированную зону для выполнения программ).

Нарушение переносимости программы

Поскольку Reflection API позволяет коду выполнять операции, которые обычно находятся под запретом, например получать доступ к закрытым полям и методам, использование рефлексии может сделать код неработоспособным и нарушить переносимость с одной операционной системы на другую. Кроме того, рефлексивный код нарушает абстракции, поэтому может изменить поведение программы при обновлении платформы.

Пример работы Reflection API в Java

Чтобы использовать Java Reflection API, не нужно подключать сторонние библиотеки. Все расположено в пакете java.lang.reflect.

Продемонстрируем некоторые методы рефлексии в программировании на конкретных примерах.

// Демонстрация работы Рефлексии в Java

import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;

// Создание объектов для класса Sample

class Sample
{

// Создаем приватное поле private

String s;

// Создаем публичный конструктор

public Sample() { s = «Java Reflection API»; }

// Создаем публичный метод без параметров

public void method1() {
System.out.println(«Информация в строке — » + s); }

// Создаем публичный метод с целым числом в качестве параметра

public void method2(int x) {
System.out.println(«Целое число — » + x);

}

// Создаем приватный метод

private void method3() {
System.out.println(«Вызов приватного метода»);
}
}
class Exercise

{
public static void main(String args[]) throws Exception
{

// Создаем объект для последующей проверки свойств

Sample obj = new Sample();

// Создаем новый объект класса из другого объекта

Class cls = obj.getClass();
System.out.println(«Имя класса — » +
cls.getName());

// Получаем имя конструктора класса с помощью объекта

Constructor constructor = cls.getConstructor();
System.out.println(«Имя конструктора — » +
constructor.getName());
System.out.println(«Это публичные методы классов: «);

// Получаем методы классов с помощью объектов

Method[] methods = cls.getMethods();

// Выводим имена методов

for (Method method:methods)
System.out.println(method.getName());

// Создаем объект нужного метода с помощью имени метода и параметра класса

Method methodcall1 = cls.getDeclaredMethod(«method2», int.class);

// Вызов метода во время исполнения

methodcall1.invoke(obj, 25);

// Создаем объект нужного поля с помощью имени поля

Field field = cls.getDeclaredField(«s»);

// Открываем доступ к полю независимо от используемого в нем спецификатора доступа

field.setAccessible(true);

// Устанавливаем новое значение поля

field.set(obj, «SkillFactory»);

// Создаем объект метода с помощью имени метода

Method methodcall2 = cls.getDeclaredMethod(«method1»);

// Вызов метода во время исполнения

methodcall2.invoke(obj);

// Создаем третий объект метода с помощью имени метода

Method methodcall3 = cls.getDeclaredMethod(«method3»);

// Изменяем настройки доступа

methodcall3.setAccessible(true);

// Вызов метода во время исполнения

methodcall3.invoke(obj);
}
}

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

Другие термины на букву «J»

Java
Java Core
JavaScript
JDBC
JDK
Jetty
Jira
JOIN
jQuery
JSON

Все термины

Освойте новую профессию

(рейтинг: 5, голосов: 3)
Добавить комментарий