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<T> { 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<User> foo = JSONObject.parseObject(jsonStr, Foo.class); leads to a ClassCastException because Fastjson cannot infer the generic type.
Using a forced cast
Foo<?> foo = (Foo<User>) 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<User> foo2 = JSONObject.parseObject(jsonStr, new TypeReference<Foo<User>>(){});
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<String,Integer>(){}) 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
