제이온

[Java] Концепция Reflection и способы использования

  • Язык написания: Корейский
  • Страна: Все страныcountry-flag
  • ИТ

Создано: 2024-04-25

Создано: 2024-04-25 22:27

Что такое Reflection?

Рефлексия — это API, который позволяет создавать экземпляры нужного класса через объект типа Class, загруженный в кучу, а также получать доступ к полям и методам экземпляра независимо от модификаторов доступа.



Здесь «загруженный класс» означает, что загрузчик классов JVM завершил загрузку файла класса и создал объект типа Classсодержащий информацию о данном классе, и сохранил его в куче. Обратите внимание, что это отличается от объекта, создаваемого с помощью ключевого слова new. Если вам не понятен объект типа Class, ознакомьтесь с документацией JDK для java.lang.class.


Способ использования

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


  • Получение с помощью Class.class
  • Получение с помощью Instance.getClass()
  • Получение с помощью Class.forName("Имя класса")


Можно убедиться, что экземпляры типа Class, полученные тремя способами, идентичны. Хэш-коды одинаковы независимо от используемого способа, поэтому следует использовать подходящий способ в зависимости от ситуации.


Теперь, используя полученный тип Class, мы можем создавать экземпляры данного класса и получать доступ к его полям и методам независимо от модификаторов доступа. Давайте начнем с создания экземпляра класса.


С помощью getConstructor() можно получить конструктор, а с помощью newInstance() — динамически создать экземпляр Member.

Наконец, давайте получим доступ к полям и методам экземпляра независимо от модификаторов доступа.

С помощью getDeclaredFileds() можно получить все переменные экземпляра класса, а с помощью get() — вернуть значение поля, а с помощью set() — изменить значение поля. При этом важно помнить, что при доступе к полю с модификатором доступа private необходимо передать в setAccessible() значение true.


Методы также можно получить с помощью getDeclaredMethod(). При этом в качестве аргументов необходимо передать имя метода и тип его параметров. Аналогично, при доступе к методу с модификатором доступа private необходимо установить для setAccessible() значение true. Наконец, с помощью метода invoke() можно вызвать метод, полученный с помощью API рефлексии.


Преимущества и недостатки

  • Преимущества
    • Гибкость: позволяет во время выполнения создавать экземпляры классов и получать доступ к полям и методам независимо от модификаторов доступа, выполняя необходимые действия.
  • Недостатки
    • Нарушение инкапсуляции.
    • Поскольку экземпляр создается во время выполнения, тип нельзя проверить во время компиляции.
    • Поскольку экземпляр создается во время выполнения, сложно отследить конкретный ход выполнения программы.
    • Доступ к полям и методам с помощью рефлексии может быть медленнее, чем прямой доступ (не во всех случаях).


Причины использования

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


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


Например, в Spring Bean Factory, если вы добавите аннотации @Controller, @Service, @Repository, Bean Factory автоматически создаст и будет управлять классами с этими аннотациями. Разработчик не передавал эти классы в Bean Factory, но это возможно благодаря рефлексии. Во время выполнения Bean Factory ищет классы с указанными аннотациями, и если находит их, то с помощью рефлексии создает экземпляры этих классов, вводит необходимые поля и сохраняет их в Bean Factory.


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


Источники

Комментарии0

DI на уровне фреймворка: под силу даже начинающим разработчикам Node.jsСтатья описывает реализацию внедрения зависимостей (DI) в разработке серверов Node.js. Рассматриваются способы реализации DI с использованием функции метаданных Reflect компилятора TypeScript, а также соответствующие библиотеки.
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

November 8, 2024

Получение неизменяемых значений с помощью genericПредставляем способ простой передачи неизменяемых значений в generic с помощью нового ключевого слова TypeScript 5.0. Может использоваться с массивами или литеральными типами, что способствует разработке библиотек и улучшению пользовательского опыта.
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

October 30, 2024

Опыт участия в проектах с открытым исходным кодомЭта статья делится опытом участия в проектах с открытым исходным кодом и вдохновляет на преодоление страха и совершение первого шага. Она рассказывает о процессе обретения уверенности и роста, начиная с небольших улучшений.
seungwon
seungwon
seungwon
seungwon

May 3, 2025

LLM для младших школьниковПонятное объяснение концепции LLM даже для младших школьников! LLM — это ИИ, который отвечает текстом на текстовые вопросы, выполняя различные задачи, такие как кодирование и анализ изображений. Сегодня разработчики используют ИИ как инструмент.
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

March 4, 2025

Создание AI Full Stack с использованием открытого кодаМы представляем различные инструменты для построения AI Full Stack на основе открытого кода, включая LLM, инструменты вывода и обслуживания, фреймворки и решения для мониторинга. Изучите разработку AI-приложений с использованием LangChain, LlamaIndex и др
RevFactory
RevFactory
RevFactory
RevFactory

February 5, 2024

29.11.2024 Поздние новости: платная подписка на Replit / Хорошие привычки в разработке ПОВ записи блога от 29 ноября 2024 года мы делимся опытом использования платной подписки на Replit и представляем 10 хороших привычек в разработке программного обеспечения. Обсуждаются стратегии эффективного кодирования и рефакторинга, а также важность тес
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 29, 2024