Understanding Generic Type Erasure and Fastjson Deserialization with TypeReference in Java
This article explains how Java's generic type erasure affects Fastjson deserialization, demonstrates common mistakes, and shows the correct way to deserialize generic fields using Fastjson's TypeReference, while also revealing the inner workings of TypeReference through reflection and anonymous classes.
In a previous article we discussed Java generic type erasure; this post addresses how to deserialize a generic entity using Fastjson and why the process can be confusing.
We define a generic class @Data public class Foo { private String val; private T obj; } and observe that after compilation the generic type T is erased to Object . When Fastjson parses JSON without specifying the generic type, the obj field is deserialized as a JSONObject instead of the expected User object.
Two incorrect attempts are shown:
Directly specifying Foo foo = JSONObject.parseObject(jsonStr, Foo.class); leads to a ClassCastException because Fastjson cannot infer the generic type.
Using a forced cast Foo foo = (Foo ) JSONObject.parseObject(jsonStr, Foo.class); compiles but still yields a JSONObject for obj .
The proper solution is to use Fastjson's TypeReference :
public class TypeRefTest {
public static void main(String[] args) {
String jsonStr = "{\"obj\":{\"name\":\"Hydra\",\"age\":\"18\"},\"val\":\"str\"}";
Foo
foo2 = JSONObject.parseObject(jsonStr, new TypeReference
>(){});
System.out.println(foo2);
System.out.println(foo2.getObj().getClass());
}
}Running this prints Foo(val=str, obj=User(name=Hydra, age=18)) and confirms that obj is of type User .
The article then dives into how TypeReference works: an anonymous subclass is created, its constructor captures the generic superclass via getClass().getGenericSuperclass() , extracts the actual type argument with ((ParameterizedType) superClass).getActualTypeArguments()[0] , and caches it. This constructor is invoked twice—once for the static LIST_STRING field and once for the anonymous subclass used in deserialization.
To illustrate generic type retrieval, the author shows that creating an anonymous subclass of a generic class (e.g., new HashMap (){} ) allows access to the generic parameters via reflection, whereas a plain instance does not.
Finally, the article wraps up the exploration and invites readers to experiment further with the source code.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.