JavaRush /Курсы /JAVA 25 SELF /Получение информации о классах, полях, методах

Получение информации о классах, полях, методах

JAVA 25 SELF
62 уровень , 1 лекция
Открыта

1. Получение информации о полях

Чем отличаются getFields() и getDeclaredFields()

В Java у каждого класса есть поля (fields) — переменные, объявленные внутри класса. С помощью рефлексии мы можем узнать их имена, типы, модификаторы доступа (public/private), а также получить к ним доступ во время выполнения. Основной вход — объект Class<?>.

Основные методы класса Class для работы с полями:

Метод Что возвращает
getFields()
Массив всех public-полей класса, его родителей и интерфейсов
getDeclaredFields()
Массив всех полей, объявленных в этом классе

Аналогия: getFields() — как экскурсия только по выставочным залам (public), а getDeclaredFields() — ещё и по техническим помещениям (private, protected, package-private).

Пример: выводим все поля класса

Допустим, у нас есть класс:

public class Person {
    public String name;
    private int age;
    protected String email;
}

Получим информацию о полях:

import java.lang.reflect.Field;

Class<?> clazz = Person.class;

// Все public-поля (включая унаследованные)
System.out.println("Public fields:");
for (Field field : clazz.getFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

// Все объявленные поля (включая private, только свои)
System.out.println("\nDeclared fields:");
for (Field field : clazz.getDeclaredFields()) {
    System.out.println(field.getName() + " : " + field.getType().getSimpleName());
}

Результат:

Public fields:
name : String

Declared fields:
name : String
age : int
email : String

Как узнать модификаторы поля?

Каждое поле (Field) имеет модификаторы (public/private/protected, static, final и т.д.). Их можно получить через getModifiers() и преобразовать в строку с помощью Modifier:

import java.lang.reflect.Modifier;

for (Field field : clazz.getDeclaredFields()) {
    int mods = field.getModifiers();
    System.out.println(field.getName() + " : " + Modifier.toString(mods));
}

2. Получение информации о методах

Методы getMethods() и getDeclaredMethods()

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

Метод Что возвращает
getMethods()
Все public методы класса и его родителей (включая Object)
getDeclaredMethods()
Все методы, объявленные в этом классе (включая private)

Пример: выводим все методы класса

import java.lang.reflect.Method;

System.out.println("Public methods:");
for (Method method : clazz.getMethods()) {
    System.out.println(method.getName());
}

System.out.println("\nDeclared methods:");
for (Method method : clazz.getDeclaredMethods()) {
    System.out.println(method.getName());
}

Результат (для Person):

Public methods:
getClass
hashCode
equals
toString
notify
notifyAll
wait
wait
wait

Declared methods:
(ничего, если в Person не объявлено своих методов)

Добавим метод в Person:

public class Person {
    public String name;
    private int age;
    protected String email;

    public void sayHello() {
        System.out.println("Hi!");
    }
}

Теперь getDeclaredMethods() покажет и его.

Как узнать параметры и возвращаемый тип метода?

for (Method method : clazz.getDeclaredMethods()) {
    System.out.print(Modifier.toString(method.getModifiers()) + " ");
    System.out.print(method.getReturnType().getSimpleName() + " ");
    System.out.print(method.getName() + "(");
    Class<?>[] params = method.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Вывод:

public void sayHello();

3. Получение информации о конструкторах

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

Метод Что возвращает
getConstructors()
Все public конструкторы
getDeclaredConstructors()
Все конструкторы, объявленные в классе

Пример: выводим все конструкторы класса

import java.lang.reflect.Constructor;

System.out.println("Constructors:");
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
    System.out.print(clazz.getSimpleName() + "(");
    Class<?>[] params = constructor.getParameterTypes();
    for (int i = 0; i < params.length; i++) {
        System.out.print(params[i].getSimpleName());
        if (i < params.length - 1) System.out.print(", ");
    }
    System.out.println(");");
}

Если в классе объявлен только конструктор по умолчанию, он тоже будет выведен.

4. Аннотации: как узнать, чем помечен класс, метод или поле

Аннотации — это специальные метки, которые можно навешивать на классы, методы, поля и параметры. С помощью рефлексии можно узнать, какие аннотации есть у элемента.

Получение аннотаций

  • Для класса: clazz.getAnnotations()
  • Для метода: method.getAnnotations()
  • Для поля: field.getAnnotations()

Пример: проверим наличие аннотации @Deprecated

for (Method method : clazz.getDeclaredMethods()) {
    if (method.isAnnotationPresent(Deprecated.class)) {
        System.out.println(method.getName() + " is @Deprecated");
    }
}

Пример: выводим все аннотации класса

for (var annotation : clazz.getAnnotations()) {
    System.out.println(annotation);
}

5. Практика: мини-программа для анализа структуры класса

Давайте соберём всё вместе и напишем небольшую утилиту, которая по имени класса выводит его структуру: поля, методы, конструкторы и аннотации.

Пример кода: ClassInspector

import java.lang.reflect.*;
import java.util.Scanner;

public class ClassInspector {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введите полное имя класса (например, java.util.ArrayList): ");
        String className = scanner.nextLine();

        Class<?> clazz = Class.forName(className);

        System.out.println("\n== Класс: " + clazz.getName() + " ==");

        // Аннотации класса
        System.out.println("Аннотации:");
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println("  " + annotation);
        }

        // Поля
        System.out.println("\nПоля:");
        for (Field field : clazz.getDeclaredFields()) {
            System.out.println("  " + Modifier.toString(field.getModifiers())
                    + " " + field.getType().getSimpleName()
                    + " " + field.getName());
        }

        // Методы
        System.out.println("\nМетоды:");
        for (Method method : clazz.getDeclaredMethods()) {
            System.out.print("  " + Modifier.toString(method.getModifiers())
                    + " " + method.getReturnType().getSimpleName()
                    + " " + method.getName() + "(");
            Class<?>[] params = method.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }

        // Конструкторы
        System.out.println("\nКонструкторы:");
        for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
            System.out.print("  " + Modifier.toString(constructor.getModifiers())
                    + " " + clazz.getSimpleName() + "(");
            Class<?>[] params = constructor.getParameterTypes();
            for (int i = 0; i < params.length; i++) {
                System.out.print(params[i].getSimpleName());
                if (i < params.length - 1) System.out.print(", ");
            }
            System.out.println(");");
        }
    }
}

Как это работает?

  • Пользователь вводит полное имя класса (например, "java.util.ArrayList" или свой класс).
  • Программа динамически загружает класс и выводит его аннотации, поля, методы и конструкторы.
  • Попробуйте на стандартных классах JDK — увидите, сколько всего интересного скрыто внутри!

6. Полезные нюансы и визуализация

Визуальная схема: что можно узнать о классе через рефлексию

graph TD A[Class<?>] --> B["getFields/getDeclaredFields"] A --> C[getMethods/getDeclaredMethods] A --> D[getConstructors/getDeclaredConstructors] A --> E[getAnnotations] B --> F[Field: тип, имя, модификаторы] C --> G[Method: возвращаемый тип, параметры] D --> H[Constructor: параметры] E --> I["Annotation[]"]

Таблица: где искать информацию

Что хотим узнать Как получить через рефлексию
Все public-поля
clazz.getFields()
Все объявленные поля
clazz.getDeclaredFields()
Все public-методы
clazz.getMethods()
Все объявленные методы
clazz.getDeclaredMethods()
Все public-конструкторы
clazz.getConstructors()
Все объявленные конструкторы
clazz.getDeclaredConstructors()
Аннотации класса
clazz.getAnnotations()
Аннотации метода/поля
method.getAnnotations(), field.getAnnotations()
Модификаторы
Modifier.toString(field.getModifiers())

7. Типичные ошибки при работе с рефлексией

Ошибка №1: Путают getFields() и getDeclaredFields().
Если вы ищете private-поля, используйте getDeclaredFields(), а не getFields(). Первый возвращает все поля, объявленные в классе, а второй — только public (и унаследованные!).

Ошибка №2: Не обрабатывают checked-исключения.
Многие методы рефлексии бросают исключения (например, ClassNotFoundException или SecurityException). Не забывайте обрабатывать их или объявлять в сигнатуре метода.

Ошибка №3: Не учитывают модификаторы доступа.
Доступ к private-полям и методам возможен только после вызова setAccessible(true), иначе будет IllegalAccessException. Пример:

Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // Открываем доступ к private-полю
int value = (int) field.get(person);

Ошибка №4: Ожидают увидеть только свои методы/поля.
getMethods() и getFields() возвращают public-члены не только текущего класса, но и всех его родителей, включая Object. Это может удивить, если вы ожидаете увидеть только то, что написали сами.

Ошибка №5: Не проверяют наличие аннотаций правильно.
Используйте isAnnotationPresent() для проверки конкретной аннотации, а не перебирайте вручную массив аннотаций без нужды.

1
Задача
JAVA 25 SELF, 62 уровень, 1 лекция
Недоступна
Аудит секретного устройства 🕵️
Аудит секретного устройства 🕵️
1
Задача
JAVA 25 SELF, 62 уровень, 1 лекция
Недоступна
Каталогизация древних ритуалов 📜
Каталогизация древних ритуалов 📜
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ