java.lang.Class
Class<T> — runtime-представление загруженного типа. Объекты, интерфейсы, массивы, примитивы и void имеют свои Class-объекты. Создать Class обычным конструктором нельзя: их создаёт JVM и загрузчики.
Class<String> stringType = String.class;
Class<?> runtimeType = value.getClass();
Class<?> arrayType = int[].class;
Class<?> primitiveType = int.class;Идентичность класса — не только полное имя, но и определивший ClassLoader. Два загрузчика могут загрузить одинаковый bytecode как два несовместимых runtime-типа.
Что можно узнать
Class<Order> type = Order.class;
String name = type.getName();
boolean record = type.isRecord();
Constructor<Order> constructor =
type.getDeclaredConstructor(String.class);
List<String> fieldNames = Arrays.stream(type.getDeclaredFields())
.map(Field::getName)
.toList();getMethods()— публичные методы, включая унаследованные;getDeclaredMethods()— методы, объявленные непосредственно здесь, любой видимости;- аналогичное различие есть для полей и конструкторов;
- generic-метаданные доступны как
Type, но runtime-объекты подчиняются type erasure.
Загрузка и инициализация
SomeType.class получает class literal без обязательного запуска static-инициализатора. Class.forName("pkg.SomeType") по умолчанию загружает и инициализирует тип. Перегрузка с initialize = false разделяет эти действия.
Class<?> metadataOnly = Class.forName(
"example.Plugin",
false,
pluginLoader
);Ограничения
- reflection может быть ограничена модулями и доступом;
Class.forNameсо строкой переносит ошибку имени в runtime;- хранение
Class<?>в статическом кэше может удерживать pluginClassLoader; Class.newInstance()устарел; нуженgetDeclaredConstructor().newInstance().
На собеседовании
Могут ли два класса с одним именем быть разными? Да, если их определили разные загрузчики.
Чем getMethods отличается от getDeclaredMethods? Первый возвращает доступные публичные, включая наследованные; второй — объявленные в классе.
Инициализирует ли Type.class класс? Само class literal обычно нет.
Как получить Class примитива? Например, int.class или Integer.TYPE.
Связано: Понятие рефлективность Java, Class loader, Аннотации.