Бесплатный вебинар
«как найти любимую работу»
Подарки на 150 000 ₽ за участие
Живой эфир
Записи не будет!
00:00:00:00
дн.ч.мин.сек.

Доступ к наследуемым атрибутам Java через Reflection API

Быстрый ответ

В Java присутствует возможность, с помощью Reflection API, получить доступ к полям (в том числе приватным и защищенным) не только конкретного объекта, но и его родительских классов. Для этого вам потребуется поэтапно обходить иерархию классов с применением метода getDeclaredFields, с предварительной установкой доступа к каждому из полей.

Java
Скопировать код
Object obj = // ... создаем объект для анализа
Class<?> cls = obj.getClass();
while (cls != null) {
    for (Field field : cls.getDeclaredFields()) {
        field.setAccessible(true); // Обеспечиваем доступ к приватным и защищенным полям
        System.out.println(field.getName() + ": " + field.get(obj));
    }
    cls = cls.getSuperclass(); // Продолжаем перебор суперклассов
}

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

Кинга Идем в IT: пошаговый план для смены профессии

Обдуманный выбор способа получения полей

Хотя инструменты "из коробки" удобны в использовании, порой требуется более детальная настройка. Если вам необходимо не просто выводить поля, но и сохранять их список для последующей работы, то следует использовать следующий метод.

Собираем все поля в один список

Вот метод для сбора полей классов и их суперклассов, который добавляет их в переданный список:

Java
Скопировать код
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
    fields.addAll(Arrays.asList(type.getDeclaredFields())); // Добавляем текущие поля
    
    if (type.getSuperclass() != null) { // Если есть суперкласс, ищем его поля
        fields = getAllFields(fields, type.getSuperclass()); // Идем вглубь по иерархии — метод рекурсивно вызывает сам себя
    }
    return fields; // Возвращаем наполненный список
}
Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Применение Apache Commons

Для упрощения процесса можно использовать готовый метод FieldUtils.getAllFieldsList из библиотеки Apache Commons Lang (главное, чтобы версия была не ниже 3.2):

Java
Скопировать код
List<Field> allFields = FieldUtils.getAllFieldsList(obj.getClass());
for (Field field : allFields) {
    field.setAccessible(true);
    System.out.println(field.getName()); // Сразу выводим имена полей
}

Не забываем про тестирование

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

Визуализация

Можно воспринимать атрибуты класса как ценности, передающиеся по наследству:

Markdown
Скопировать код
Ящик базового класса 📦: содержит [🔑ключ, 🔓замок]
Ящик производного класса 📦: получил в наследство 🔑ключ, 🔓замок, добавил 🏷️этикетку

Применимо к написанию кода:

Java
Скопировать код
getDeclaredFields() // 🗝️📦 Открываем сундук собственных атрибутов
getFields() // 🔑🔗🔓 Ищем ключи и замки во всей цепочке наследования

Графическая иллюстрация принципа работы:

Markdown
Скопировать код
🔍 Java Reflection
  📦 Базовый класс:       [🔑, 🔓]
  📦 Производный класс:   [🔑, 🔓, 🏷️] (хранит в себе как собственные, так и унаследованные ценности)

🔍 = Инструмент Reflection в Java
🔑🔗🔓 = Анализ ключей и замков в иерархической цепочке наследования

Обращение с обобщениями

Применение Class<?> в коде обеспечивает его универсальность и гибкость: методы могут применяться к различным классам.

Избегим дублирования

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

Воспользуемся дополнительной поддержкой

Не стесняйтесь использовать сторонние библиотеки, например, Apache Commons Lang. Они помогают уменьшить объем рутинного кода и упростить выполнение задач, связанных с Reflection.

Полезные материалы

  1. Trail: The Reflection API (The Java™ Tutorials) — детальное руководство по Reflection API в Java.
  2. Class (Java Platform SE 8 ) — документация, посвященная классу Class в Java.
  3. Retrieving the inherited attribute names/values using Java Reflection – Stack Overflow — обсуждение использования Reflection для доступа к наследуемым атрибутам.
  4. A Comprehensive Guide to Java Reflection – DZone — подробное введение в Java Reflection.
  5. Java Reflection Example Tutorial | DigitalOcean — практическое руководство с примерами использования Java Reflection.
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Как получить доступ к полям родительских классов в Java с помощью Reflection API?
1 / 5