Основы рефлексии
Class — описание типа во время выполнения
Обычно Java-код работает с объектами и вызывает известные заранее методы.
Reflection нужен, когда программе требуется исследовать сам тип во время выполнения:
узнать его имя, родительский класс, интерфейсы, аннотации или доступные члены.
Точкой входа служит объект Class<?>.
Class<String> type = String.class;
System.out.println(type.getName());
System.out.println(type.getSimpleName());
Объект Class не является экземпляром String.
Он представляет описание самого типа String в работающей JVM.
Как получить Class
Когда тип известен в коде, проще всего использовать литерал .class.
Если уже есть объект, его тип можно получить через getClass().
String text = "hello";
Class<String> first = String.class;
Class<? extends String> second = text.getClass();
Когда имя класса приходит как строка во время выполнения, существует
Class.forName(). Такой вариант встречается в инфраструктурном коде,
где конкретный тип заранее неизвестен исходному коду.
Class<?> type = Class.forName("java.util.ArrayList");
System.out.println(type.getSimpleName());
Что можно узнать о типе
Через Class можно проверить, представляет ли объект интерфейс, enum, record или массив,
получить пакет, суперкласс и реализованные интерфейсы, а также перейти к полям, методам,
конструкторам и аннотациям. Эти группы мы разберём отдельно, чтобы не превращать Reflection в список методов API.