Вопрос проверяет понимание ограничений generics в runtime и того, как библиотеки обходят type erasure.
ObjectMapper не может сам определить generic-типы во время выполнения.
Из-за type erasure информация о параметрах типов теряется.
Поэтому тип нужно передавать явно.
Для этого используются специальные конструкции Jackson.
Без этого десериализация приведёт к сырым типам или ошибкам.
Jackson вынужден работать в условиях отсутствия информации о generic-типах в runtime.
При попытке:
List<User> users = objectMapper.readValue(json, List.class);
Jackson:
знает только List
не знает, что элементы — User
В результате:
элементы десериализуются как LinkedHashMap
Jackson принимает описание типа, а не сам класс:
через TypeReference
через JavaType
TypeReferenceList<User> users =
objectMapper.readValue(
json,
new TypeReference<List<User>>() {}
);
Здесь:
анонимный класс сохраняет информацию о типе
Jackson извлекает generic-параметры через reflection
JavaType type = objectMapper
.getTypeFactory()
.constructCollectionType(List.class, User.class);
List<User> users = objectMapper.readValue(json, type);
Для корректной десериализации generic-коллекций Jacksonу нужно явно передать информацию о параметрах типов.