This is a well-known problem with Java type erasure: T is just a type variable, and you must indicate actual class, usually as Class argument. Without such information, best that can be done is to use bounds; and plain T is roughly same as 'T extends Object'. And Jackson will then bind JSON Objects as Maps.

In this case, tester method needs to have access to Class, and you can construct

JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)

and then

List<Foo> list = mapper.readValue(new File("input.json"), type);
Answer from StaxMan on Stack Overflow
🌐
Fasterxml
fasterxml.github.io › jackson-core › javadoc › 2.2.0 › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference (Jackson-core 2.2.0 API)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.
🌐
GitHub
github.com › FasterXML › jackson-1 › blob › master › src › java › org › codehaus › jackson › type › TypeReference.java
jackson-1/src/java/org/codehaus/jackson/type/TypeReference.java at master · FasterXML/jackson-1
* to generic type <code>List&lt;Integer></code>: *<pre> * TypeReference ref = new TypeReference&lt;List&lt;Integer>>() { }; *</pre> * which can be passed to methods that accept TypeReference. */ public abstract class TypeReference<T> implements Comparable<TypeReference<T>> { final Type _type; ·
Author: FasterXML
Discussions

java - Jackson and generic type reference - Stack Overflow
I want to use jackson json library for a generic method as follows: public MyRequest tester() { TypeReference More on stackoverflow.com
🌐 stackoverflow.com
Writing a jackson type reference
You can add the jackson-module-kotlin dependency https://github.com/FasterXML/jackson-module-kotlin It adds some extension functions, including a new readValue that doesn't require a TypeReference because it's an inline function that makes the TypeReference for you, allowing you to write import com.fasterxml.jackson.module.kotlin.readValue ... val names: List = mapper.readValue(json) Also, Kotlin does have a special typeOf() function that does exactly what you describe, although doesn't look like this jackson module uses it More on reddit.com
🌐 r/Kotlin
2
1
October 24, 2024
java - Jackson - Deserialising JSON string - TypeReference vs TypeFactory.constructCollectionType - Stack Overflow
Can this class, SomeClass be made generic and have the same way a list is constructed from JSON? 2021-05-05T05:45:29.61Z+00:00 ... Yes, you could have SomeClass and it could be used via TypeReference or dynamically constructed; and deserialization should work as well. More on stackoverflow.com
🌐 stackoverflow.com
What is TypeReference in java which is used while converting a JSON script to MAP - Stack Overflow
So your HashMap will just be HashMap when your programme runs. So Jackson cannot determine the types Stringand Object. That is why you have to create a TypeReference which will preserve that information at runtime so Jackson can deserialise your JSON String into the correct ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Fasterxml
fasterxml.github.io › jackson-core › javadoc › 1.9 › org › codehaus › jackson › type › TypeReference.html
TypeReference (Jackson JSON Processor)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference.
🌐
Northcoder
northcoder.com › post › jackson-object-mapper-which-way-is
Jackson's ObjectMapper and TypeReference | northCoder
January 15, 2021 - TypeReference is an abstract class. The {} provides an empty implementation via an anonymous class, without which you would get a compile-time error: ... You may sometimes (rarely?) see {{}} syntax - this is Java’s double brace initialization. Consider this code: ... This creates a list containing two values.
Top answer
1 of 3
267

This is a well-known problem with Java type erasure: T is just a type variable, and you must indicate actual class, usually as Class argument. Without such information, best that can be done is to use bounds; and plain T is roughly same as 'T extends Object'. And Jackson will then bind JSON Objects as Maps.

In this case, tester method needs to have access to Class, and you can construct

JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)

and then

List<Foo> list = mapper.readValue(new File("input.json"), type);
2 of 3
12

'JavaType' works !! I was trying to unmarshall (deserialize) a List in json String to ArrayList java Objects and was struggling to find a solution since days.
Below is the code that finally gave me solution. Code:

JsonMarshallerUnmarshaller<T> {
    T targetClass;

    public ArrayList<T> unmarshal(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();

        AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
        mapper.getDeserializationConfig()
            .withAnnotationIntrospector(introspector);

        mapper.getSerializationConfig()
            .withAnnotationIntrospector(introspector);
        JavaType type = mapper.getTypeFactory().
            constructCollectionType(
                ArrayList.class, 
                targetclass.getClass());

        try {
            Class c1 = this.targetclass.getClass();
            Class c2 = this.targetclass1.getClass();
            ArrayList<T> temp = (ArrayList<T>) 
                mapper.readValue(jsonString,  type);
            return temp ;
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null ;
    }  
}
🌐
Reddit
reddit.com › r/kotlin › writing a jackson type reference
r/Kotlin on Reddit: Writing a jackson type reference
October 24, 2024 -

I'm using a jackson object mapper to deserialize json. If I need to get a List<String>, I need to pass a type reference because neither java nor Kotlin let me write List<String>.class. In java the type reference is

new TypeReference<List<String>>() {}

while in Kotlin is

object : TypeReference<List<String>>() {}

And this is the only simple case when the kotlin code is longer than the java code. And it is also as horrible as the java version

Am I doing something wrong?

Since what jackson really needs is a type, I wish we could have a special syntax for this case, kotlink could let us write generic-type-of(List<Integer>) and return a nice type...

🌐
Adobe Developer
developer.adobe.com › experience-manager › reference-materials › 6-5 › javadoc › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference (The Adobe AEM Quickstart and Web Application.)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.
Find elsewhere
🌐
Javadoc.io
javadoc.io › doc › com.fasterxml.jackson.core › jackson-core › latest › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference - jackson-core 2.22.3 javadoc
https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/2.22.3 · package-list path (used for javadoc generation -link option) https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/2.22.3/package-list · Manage versions · https://javadoc.io/versions/com.fasterxml.jackson.core/jackson-core ·
Top answer
1 of 2
26

In Java generics are more or less gone at runtime. This is called type erasure. So your HashMap<String, Object> will just be HashMap<?, ?> when your programme runs. So Jackson cannot determine the types Stringand Object. That is why you have to create a TypeReference which will preserve that information at runtime so Jackson can deserialise your JSON String into the correct classes.

If you don't specify a type Jackson will still be able to correctly deserialise simple objects like String or numbers but when a more complex object is encountered it will simply deserialise them into LinkedHashMap which will then most likely lead to a ClassCastException when you try to access the deserialised object.

2 of 2
9

This TypeReference<T> implements Comparable<TypeReference<T>> is part of jackon library. And this is part of com.fasterxml.jackson.core.type. From the API documentation:

This generic abstract class is used for obtaining full generics type information by sub-classing; it must be converted to ResolvedType implementation (implemented by JavaType from "databind" bundle) to be used. Class is based on ideas from http://gafter.blogspot.com/2006/12/super-type-tokens.html, Additional idea (from a suggestion made in comments of the article) is to require bogus implementation of Comparable (any such generic interface would do, as long as it forces a method with generic type to be implemented). to ensure that a Type argument is indeed given. Usage is by sub-classing: here is one way to instantiate reference to generic type List:

TypeReference ref = new TypeReference<List>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.

This is basically used to de-serialize the Generic type of JSON objects, for example the JAVA Collection objects as below:

public List<Double> getDoubleList() {

  return getObjectFromJson(new TypeReference<List<Double>>() {
  });
}


public <T> T getObjectFromJson(String jsonString, final TypeReference<T> typeReference) {
  try {
    return new ObjectMapper().readValue(jsonString, typeReference);
  } catch (JsonProcessingException e) {
    // TODO
  }
}
🌐
Fasterxml
fasterxml.github.io › jackson-core › javadoc › 2.12 › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference (Jackson-core 2.12.0 API)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.
🌐
Javadoc.io
javadoc.io › doc › org.codehaus.jackson › jackson-core-asl › 1.9.13 › org › codehaus › jackson › type › TypeReference.html
TypeReference - jackson-core-asl 1.9.13 javadoc
https://javadoc.io/doc/org.codehaus.jackson/jackson-core-asl/1.9.13 · package-list path (used for javadoc generation -link option) https://javadoc.io/doc/org.codehaus.jackson/jackson-core-asl/1.9.13/package-list ·
🌐
Adobe Developer
developer.adobe.com › experience-manager › reference-materials › cloud-service › javadoc › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference (The Adobe Experience Manager SDK 2022.11.9850.20221116T162329Z-220900)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.
🌐
Fasterxml
fasterxml.github.io › jackson-core › javadoc › 2.8 › com › fasterxml › jackson › core › type › TypeReference.html
TypeReference (Jackson-core 2.8.0 API)
Usage is by sub-classing: here is one way to instantiate reference to generic type List<Integer>: TypeReference ref = new TypeReference<List<Integer>>() { }; which can be passed to methods that accept TypeReference, or resolved using TypeFactory to obtain ResolvedType.
🌐
Medium
medium.com › @poojaauma › enhancing-deserialization-safety-in-java-with-typereference-ea110ece6994
Enhancing Deserialization Safety in Java with TypeReference | by Umadevi R | Medium
November 7, 2024 - When working with JSON in Java, you’ve probably come across situations where deserializing JSON into complex or generic types like List<User> or Map<String, Object> can be challenging. Java’s type erasure makes it hard for libraries like Jackson to determine the exact type of collection elements, which can lead to runtime errors or even vulnerabilities. Fortunately, Jackson’s TypeReference offers a solution to these problems.
🌐
Java Tips
javatips.net › api › com.fasterxml.jackson.core.type.typereference
Java Examples for com.fasterxml.jackson.core.type.TypeReference
/** * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext) */ @Override public HeaderMap deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { HeaderMap map = new HeaderMap(); List<Entry<String, String>> entries = p.readValueAs(new TypeReference<List<Entry<String, String>>>() { }); for (Entry<String, String> entry : entries) { String key = entry.getKey(); String val = entry.getValue(); map.add(key, val); } return map; }
🌐
Stack Overflow
stackoverflow.com › questions › 69526772 › how-to-get-a-jackson-typereference-from-certain-type-of-listsome-class
java - How to get a Jackson TypeReference from certain type of List<some class>? - Stack Overflow
List<MyPojo> list = buildMyPojoList(); String json = getObjectMapper().writeValueAsString(list); getObjectMapper().readValue(json, new TypeReference<List<MyPojo>>(){});