Инспектирование классов с помощью рефлексии
Получайте объекты Class и во время выполнения изучайте поля, методы, конструкторы и аннотации.
«Инспектирование классов с помощью рефлексии» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Что такое рефлексия
Рефлексия позволяет программе на Java проверять и изменять собственную структуру во время выполнения — читать имена классов, поля, методы, конструкторы и аннотации, не зная их во время компиляции.
Получение объекта Class
Получите объект Class<?> с помощью литерала, getClass() или Class.forName().
Class<String> c1 = String.class; // literal
Class<?> c2 = "hello".getClass(); // from instance
Class<?> c3 = Class.forName("java.util.ArrayList"); // by nameПроверка метаданных класса
Извлеките из объекта Class имя класса, пакет, суперкласс и реализованные интерфейсы.
Class<?> c = ArrayList.class;
System.out.println(c.getName()); // java.util.ArrayList
System.out.println(c.getSimpleName()); // ArrayList
System.out.println(c.getSuperclass()); // class java.util.AbstractList
for (Class<?> iface : c.getInterfaces()) System.out.println(iface.getName());Получение объявленных полей
getDeclaredFields() возвращает все поля, объявленные в классе, включая закрытые. getFields() возвращает только открытые поля, в том числе унаследованные.
for (Field f : User.class.getDeclaredFields()) {
System.out.printf("%-10s %s%n", f.getType().getSimpleName(), f.getName());
}Получение списка методов
getDeclaredMethods() перечисляет все методы независимо от уровня доступа. Используйте getMethods(), чтобы получить открытые методы, включая унаследованные.
for (Method m : String.class.getDeclaredMethods()) {
System.out.println(m.getName() + " -> " + m.getReturnType().getSimpleName());
}Проверка параметров метода
Получите типы и имена параметров (требуется флаг компилятора -parameters), а также аннотации.
Method m = UserService.class.getDeclaredMethod("findById", Long.class);
for (Parameter p : m.getParameters()) {
System.out.println(p.getType().getSimpleName() + " " + p.getName());
}Получение списка конструкторов
Проверяйте конструкторы так же, как методы. getDeclaredConstructors() включает закрытые конструкторы, используемые в одиночках или построителях.
for (Constructor<?> c : User.class.getDeclaredConstructors()) {
System.out.println(Arrays.toString(c.getParameterTypes()));
}Чтение аннотаций
Получите аннотации класса, метода или поля. Проверяйте их наличие с помощью isAnnotationPresent, а значение получайте через getAnnotation.
@RestController
@RequestMapping("/users")
public class UserController {}
// Inspection:
RequestMapping rm = UserController.class.getAnnotation(RequestMapping.class);
if (rm != null) System.out.println("Path: " + Arrays.toString(rm.value()));Проверка модификаторов
Используйте Modifier.isPublic(), isStatic(), isFinal() и другие методы для модификаторов поля, метода или класса, чтобы фильтровать элементы по видимости.
for (Field f : User.class.getDeclaredFields()) {
int mod = f.getModifiers();
if (Modifier.isPrivate(mod)) System.out.println("private: " + f.getName());
}Проверка isAssignableFrom и instanceof
Используйте Class.isAssignableFrom(), чтобы программно проверить совместимость типов, — это эквивалент проверки с помощью оператора instanceof, но с объектами классов, известными только во время выполнения.
Class<?> parent = Collection.class;
Class<?> child = ArrayList.class;
System.out.println(parent.isAssignableFrom(child)); // true
System.out.println(child.isAssignableFrom(parent)); // falseОграничение производительности
Рефлексия в 10–50 раз медленнее прямого кода при простом доступе к полям и методам. Кэшируйте объекты Field и Method; вызовите setAccessible(true) один раз и используйте результат повторно.
private static final Field NAME_FIELD;
static {
try { NAME_FIELD = User.class.getDeclaredField("name"); NAME_FIELD.setAccessible(true); }
catch (NoSuchFieldException e) { throw new RuntimeException(e); }
}Быстрая проверка
Какой метод возвращает закрытые поля класса, но не унаследованные?
Повторение
Получайте Class с помощью литералов или forName(). Используйте getDeclaredFields/Methods/Constructors для проверки всех элементов независимо от уровня доступа. Читайте аннотации с помощью getAnnotation. Кэшируйте объекты рефлексии для повышения производительности.
Часто задаваемые вопросы
Урок «Инспектирование классов с помощью рефлексии» бесплатный?
Да — полный текст урока «Инспектирование классов с помощью рефлексии» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Инспектирование классов с помощью рефлексии»?
Получайте объекты Class и во время выполнения изучайте поля, методы, конструкторы и аннотации. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Инспектирование классов с помощью рефлексии»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Инспектирование классов с помощью рефлексии
- Вызов методов и доступ к полям
- Динамические прокси с InvocationHandler
- Производительность рефлексии и альтернативы