Лабораторная работа № 8 — «Пользовательские аннотации и Reflection API»
Студентам следует сгенерировать в ИИ почти готовый каркас. Задача — понять механизм
Создаётся аннотация:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ReportColumn { String name(); int order(); }
Затем модель/DTO:
@ReportColumn(name = "Дата", order = 1) public LocalDate getDate() { return date; }
Для runtime-обработки аннотация действительно должна иметь RetentionPolicy.RUNTIME; Java определяет политики SOURCE, CLASS и RUNTIME, причём default для @Retention, если он не задан, — CLASS.
Студент пишет:
public class AnnotationReportExporter { public String export(List<?> objects) { // получить Class // найти аннотированные методы // отсортировать по order // вызвать Method.invoke(...) // построить строку отчёта } }
Reflection API предоставляет runtime-представления классов, методов, полей и конструкторов через Class и java.lang.reflect.
Обязательный эксперимент:
Class<?> clazz = object.getClass(); for (Method method : clazz.getDeclaredMethods()) { ... }
Студент должен вывести:
имя класса; имена методов; return types; модификаторы; наличие ReportColumn.
Затем один и тот же exporter должен работать как минимум с двумя классами без if (object instanceof ...).
Это важный переход к следующей части курса: студент своими руками делает крошечный механизм, похожий по принципу на то, что позже увидит в JUnit и Spring — metadata в аннотации + runtime processing.
При этом базовая версия не должна строиться на бесконтрольном setAccessible(true). Современная reflection взаимодействует с сильной инкапсуляцией модулей; доступ к закрытым членам может зависеть от того, открыт ли пакет.
Защита: аннотация vs обычный интерфейс; @Target; @Retention; зачем RUNTIME; что представляет Class<?>; что позволяет Method; почему reflection удобна фреймворкам; почему она может ухудшать прозрачность программы и нарушать инкапсуляцию.
Вопросы для углубления: Что такое аннотации и какие бывают
Retention/Target?Как создать собственную
аннотацию и где она используется?Что такое
reflection и какие базовые операции она позволяет
выполнять?Какие типовые сценарии применения
рефлексии в Java-фреймворках?Каковы
ограничения/риски рефлексии
(производительность, безопасность,
инкапсуляция)?
