What is TypeReference in java which is used while converting a JSON script to MAP

Viewed 3044

While converting a JSON received from api response I came accross TypeRef, but I am not sure how does it works? Any pictorial representation or simplified version will be good. I read, but still not so much clear about it. Like we have map to store <K,V> but then what difference will TypeRef will do on object?

TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
2 Answers

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
  }
}

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.

Related