Рефлексия это в информатике кратко

Обновлено: 05.07.2024

Рефлексия в Java осуществляется с помощью Java Reflection API. Что такое эта рефлексия? Существует короткое и точное, а также популярное на просторах интернета определение. Рефлексия (от позднелат. reflexio — обращение назад) — это механизм исследования данных о программе во время её выполнения. Рефлексия позволяет исследовать информацию о полях, методах и конструкторах классов. Сам же механизм рефлексии позволяет обрабатывать типы, отсутствующие при компиляции, но появившиеся во время выполнения программы. Рефлексия и наличие логически целостной модели выдачи информации об ошибках дает возможность создавать корректный динамический код. Иначе говоря, понимание принципов работы рефлексии в java открывает перед вами ряд удивительных возможностей. Вы буквально можете жонглировать классами и их составляющими.

Метод newInstance() позволяет создать объект указанного класса. Но что ВАЖНО отметить — такой вызов возможен только в случае, если класс имеет конструктор БЕЗ ПАРАМЕТРОВ. Если такого конструктора в вашем классе нет, то воспользоваться таким простым вызовом не получится — придется действовать сложнее. Так что иметь конструктор без параметров — это неплохая идея.
Как вы уже возможно догадались, вызов возвращает объект класса Object и нам надо вручную привести его к нужному типу. Т.к. мы полагаемся на “порядочность” нашего класса, которая выражается в поддержке интерфейса FinanceInfoBuilder, то мы к нему и приводим наш объект.
Теперь для смены класса для загрузки финансовых показателей достаточно просто отредактировать файл builder.properties. Ничего больше. Далее следуют бурные продолжительные аплодисменты.

Проект в NetBeans можно загрузить здесь: FinanceExample

Класс Class

Мы посмотрели вариант загрузки класса и создание объекта нужного нам класса. На самом деле такой вариант использования рефлексии весьма распространен. Так что очень рекомендую запомнить это решение. Теперь мы посмотрим, как можно не только создать объект нужного класса, но и как можно обратиться к полям или методам.
Определим простой класс для наших экспериментов

И теперь “поиграем” с нашим классом — обратимся к его полю и методам через Reflection API

Итак, давайте разбираться. Метод demoReflcetion уже знакомым нам способом создает объект типа SimpleClass. В принципе этот момент был не обязателен и выглядит достаточно натянуто — смысл загружать класс и следующей строкой его же и использовать, но для демонстрации подойдет. Дальше начинаются гораздо более интересные вещи.
Метод demoReflectionField показывает способ обращения к полю (причем к приватному полю). Самое главное — это получение обхекта типа Field по имени, с помощью которого можно уже работать с конкретным полем. Дальше код демонстрирует такие возможности.
Особо хочу отметить вызов setAccessible(true), который позволяет работать с приватным полем.
Метод demoReflectionMethod демонстрирует вариант получения метода по имени и по имени и параметрам — вспоминаем, что такое overloading. Здесь уже используется другой тип — Method — с помощью которого можно вызвать конкретный метод объекта. Дальше я предлагаю вам самим запустить пример а также прочитать код и комментарии к нему.

Проект в NetBeans можно загрузить здесь: SimpleReflection

Аннотации

В версии Java 1.5 появился очень интересный и очень мощный инструмент — аннотации. По сути аннотация — это именованный блок информации, который содержит набор именованных параметров и этот блок можно “прикрепить” к классу, методу, полю и даже параметру в методе. Другими словами — у аннотации есть имя и у нее есть список параметров с именами, которые можно выставить в определенные значения.
И теперь еще раз подумайте — вы можете прикрепить к основным артефактам кода (класс, метод, поле) блок с информацией и ЭТОТ БЛОК ДОСТУПЕН через рефлексию.
И что в этом таког, можете спросить вы ? Дело в том, что теперь есть возможность написать библиотеку (набор классов), которая может обрабатывать классы с определенными аннотациями. Например, именно так работает система ORM (Object Relation Mapping) — система сохранения объектов в базу данных (если честно, то не только так). С появлением аннотаций это теперь очень несложно сделать — вы аннотируете класс, который надо сохранить в базу данных специальным набором аннотаций и все. Дальше библиотека смотрит по аннотациям в какую таблицу и какое поле этого объекта к какую колонку записывается. Там еще можно “навесить” дополнительные условия, связи и много чего еще. Скорость разработки возрастает, написание системы упрощается, становится более лаконичной.
Точно также можно делать EJB, сервлеты. JUnit работает по этому принципу. Системы автоматического создания набора нужных объектов (IoC/DI — Inversion of Control/Dependency Injection) с нужными значениями полей использует аннотации. Веб-сервисы строятся на основе аннотаций, работа с XML и много чего еще.
По сути, библиотека просто говорит вам: “если у твоего класса есть такие-то аннотации, то я смогу произвести над ним нужную тебе работу. Просто напиши нужные аннотации с нужными параметрами”.
Аннотации настолько “вросли” в различные технологии Java, что на сегодня без них работать гораздо сложнее.
Для примера я создал свою аннотацию (хотя прикладной программист чаще всего использует уже готовые) для расширения нашего примера с финансовой информацией.
Вот как выглядит аннотация (это файл .java)

Рефлексия (от reflexio - обращение назад) - это механизм исследования данных о программе во время её выполнения. Рефлексия в Java осуществляется с помощью Java Reflection API, состоящий из классов пакетов java.lang и java.lang.reflect. В информатике рефлексия означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения.

Java Reflection API позволяет получать информацию о конструкторах, методах и полях классов и выполнять следующие операции над полями и методами объекта/класса :

  • определение класса объекта;
  • получение информации о полях, методах, конструкторах и суперклассах;
  • получение информации о модификаторах полей и методов;
  • создание экземпляра класса, имя которого неизвестно до момента выполнения программы;
  • определение и изменение значений свойств объекта/класса;
  • вызов методов объекта/класса.

Примечание : в тексте используется объект/класс. При работе с объектом (реализацией класса) можно обращаться к полям и методам класса напрямую, если они доступны (не private). При работе с классом можно обращаться к методам класса с использованием Java Reflection API. Но класс необходимо получить из объекта.

Определение свойств класса

В работающем приложении для получения класса необходимо использовать метод forName (String className). Следующий код демонстрирует возможность создания класса без использования и с использованием Reflection :

Метод класса forName(className) часто используется для загрузки JDBC-драйвера.

Методом getName() объекта Class можно получить наименование класса, включающего пакет (package) :

Для получения значения модификатора класса используется метод getModifiers(). Класс java.lang.reflect.Modifier содержит статические методы, возвращающие логическое значения проверки модификатора класса :

Для получения суперкласса рефлексированного объекта (класса) необходимо использовать метод getSuperclass() :

Поскольку в Java отсутствует множественное наследование, то для получения всех предков следует рекурсивно вызвать метод getSuperclass() в цикле, пока не будет достигнут Object, являющийся родителем всех классов. Object не имеет родителей, поэтому вызов его метода getSuperclass() вернет null.

Определение интерфейсов и конструкторов класса

Для получения в режиме run-time списка реализующих классом интерфейсов, необходимо получить Class и использовать его метод getInterfaces(). В следующем примере извлекается список интерфейсов класса ArrayList :

Чтобы IDE (Eclipse) не предупреждала о необходимости определения типа класса

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

Метод класса getConstructors() позволяет получить массив открытых конструкторов типа java.lang.reflect.Constructor. После этого, можно извлекать информацию о типах параметров конструктора и генерируемых исключениях :

Определение полей класса

Метод getFields() объекта Class возвращает массив открытых полей типа java.lang.reflect.Field, которые могут быть определены не только в данном классе, но также и в его родителях (суперклассе), либо интерфейсах, реализованных классом или его родителями. Класс Field позволяет получить имя поля, тип и модификаторы :

Если известно наименование поля, то можно получить о нем информацию с помощью метода getField() объекта Class.

Методы getField() и getFields() возвращают только открытые члены данных класса. Чтобы получить все поля класса, включая закрытые и защищенные, необходимо использовать методы getDeclaredField() и getDeclaredFields(). Данные методы работают точно так же, как и их аналоги getField() и getFields().

Определение значений полей класса

Класс Field содержит специализированные методы для получения значений примитивных типов: getInt(), getFloat(), getByte() и др. Для установки значения поля, используется метод set(). Для примитивных типов имеются методы setInt(), setFloat(), setByte() и др.

Ниже приведен пример изменения значения закрытого поля класса в режиме run-time.

Определение методов класса

Метод getMethods() объекта Class возвращает массив открытых методов типа java.lang.reflect.Method. Эти методы могут быть определены не только в классе, но также и в его родителях (суперклассе), либо интерфейсах, реализованных классом или его родителями. Класс Method позволяет получить имя метода, тип возвращаемого им значения, типы параметров метода, модификаторы и генерируемые исключения.

Если известно имя метода и типы его параметров, то можно получить отдельный метод класса :

Пример изменения значения закрытого поля класса

Чтобы изменить значение закрытого (private) поля класса необходимо получить это поле методом getDeclaredField () и вызвать метод setAccessible (true) объекта Field, чтобы открыть доступ к полю. После этого значение закрытого поля можно изменять, если оно не final. В следующем примере определен внутренний класс PrivateFinalFields с набором закрытых полей; одно из полей final. При создании объекта класса поля инициализируются. В методе main примера поочередно в закрытые поля вносятся изменения и свойства объекта выводятся в консоль.

Из приведённого примера видно что поля private можно изменять. Для этого необходимо получить объект типа java.lang.reflect.Field с помощью метода getDeclaredField (), вызвать его метод setAccessible (true) и с помощью метода set () установить требуемое значение поля. Необходимо иметь в виду, что наличие модификатора final в закрытом текстовом поле не вызывает исключений при изменении значений, а само значение поля остаётся прежним, т.е. final поля остаются неизменные. Если не вызвать метод открытия доступа к полю setAccessible (true), то будет вызвано исключение java.lang.IllegalAccessException.

Пример вызова метода, invoke

Java Reflection Api позволяет вызвать метод класса. Рассмотрим пример, в котором определим класс Reflect, включающий поля и методы управления ими. В режиме run-time с помощью метода данного класса будем изменять значения полей и распечатывать их.

Листинг класса Reflect

Класс Reflect включает два закрытых поля (id, name) и методы управления их значениями set/get. Дополнительно в класс включим метод setData, который будем вызывать для изменения значений полей, и метод toString для печати их значений.

Для тестирования объекта типа Reflect с помощью Java Reflection Api создадим класс ReflectionTest. В этот класс включим две процедуры getClassFields и getClassMethods, которые в режиме run-time распечатают всю информацию (описание полей и методов) о классе. Методы получают класс в качестве параметра. В процедурах сначала определяются массивы полей и методы; после этого их параметры распечатываются :

В конструкторе класса ReflectionTest сначала вызываются процедуры определения полей и методов объекта/класса Reflect. После этого вызываются методы изменения значений и печати значений с использованием Reflection API. Для определения метода setData используется массив типов параметров. Вызов метода setData выполняется с передачей ему массива новых значений.

Исходный код рассмотренного примера вызова метода invoke с использованием Java Reflection API можно скачать здесь (989 байт).

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

Рефлексия (отражение) — это процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения, это своего рода процесс обнаружения типов во время выполнения.

Рефлексия позволяет: перечислять члены типа, создавать новые экземпляры объекта, запускать на выполнение члены объекта, извлекать информацию о типе, извлекать информацию о сборке, исследовать пользовательские атрибуты, примененные к типу, создавать и компилировать новые сборки.

Метаданные описывают все классы и члены классов, определённые в сборке, а также классы и члены классов, которые текущая сборка вызывает из другой сборки.

Манифест сборки— коллекция данных, с описанием того, как элементы любой сборки (статической или динамической) связаны друг с другом. Манифест сборки содержит все
метаданные, необходимые для задания требований сборки к версиям и удостоверения безопасности, а также все метаданные, необходимые для определения области действия сборки и разрешения ссылок на ресурсы и классы. Манифест сборки может храниться в PE-файле (EXE или DLL) с кодом MSIL или же в отдельном PE-файле, содержащем только данные манифеста.

Модули — это контейнеры типов, расположенные внутри сборки. Модуль может быть контейнером в простой, или многофайловой сборке. Несколько модулей в одной сборке применяются в редких случаях, когда нужно добавить код на разных языках в одну сборку или обеспечить поддержку выборочной загрузки модулей.

Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования.

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

Класс Type.

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



Рефлексия способствует развитию трёх важных качеств человека, которые потребуются ему в XXI в. , чтобы не чувствовать себя изгоем. Самостоятельность. Не учитель отвечает за ученика, а ученик, анализируя, осознаёт свои возможности, сам делает свой собственный выбор, определяет меру активности и ответственности в своей деятельности. Предприимчивость. Ученик осознаёт, что он может предпринять здесь и сейчас, чтобы стало лучше. В случае ошибки или неудачи не отчаивается, а оценивает ситуацию и, исходя из новых условий, ставит перед собой новые цели и задачи и успешно решает их. Конкурентоспособность. Умеет делать что - то лучше других, действует в любых ситуациях более эффективно. Рефлексия может осуществляться не только в конце урока, как это принято считать, но и на любом его этапе. Рефлексия может осуществляться по итогам не только урока, но и других временных отрезков: изучения темы, учебной четверти, года и т. п. При выборе того или иного вида рефлексии нужно учитывать цель урока, содержание и трудности учебного материала, способы и методы обучения, возрастные и психологические особенности обучающихся.


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













Читайте также: