Garmaine Staff asked 2 years ago

I've been using Jackson to serialize/deserialize objects for years and have always found it needlessly complicated to use TypeReference<T> to deserialize List etc. I created a simple helper function:

public static <T> TypeReference<List<T>> list() {
    return new TypeReference<List<T>>(){}

With intended use:

List<Foo> foos = objectMapper.readValue(json, list());

And it works! Kind of. When inspecting through the debugger, rather than a list of Foo, it is rather a list of LinkedHashMap. I understand that ObjectMapper deserializes into LinkedHashMap for type Object and I read the explanation for that here:

Jackson and generic type reference

However, why is it able to assign List<LinkedHasMap> to a List<Foo>? At the very least shouldn't that be some sort of ClassCastException?

Also, is there anyway to do this with Java's type system?

NOTE: the following method declaration has the same issue, which makes sense because the additional argument is not needed for T to be determined:

public static <T> TypeReference<List<T>> listOf(Class<T> ignored) {
    return new TypeReference<List<T>>(){}