Deserialize a List<T> object with Gson?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Deserializing a JSON array into List<T> with Gson is a very common Java task, but it has one important wrinkle: Java generics are erased at runtime. That means List<Person>.class is not valid type information for Gson, so you need to provide a Type that preserves the generic element type.
Core Sections
Why List<T>.class does not work
This is the core issue. Java erases generic type parameters at runtime, so Gson cannot infer the element type from List<T> automatically.
This will not do what you want:
Gson needs a runtime Type object that still carries the information that the list contains Person objects rather than just “some list.”
Use TypeToken for List<Person>
The normal solution is TypeToken.
The anonymous TypeToken subclass is what captures the generic parameter so Gson can build the correct object graph.
Deserializing lists of simple types
The same pattern works for lists of strings, integers, or other non-custom types.
So the technique is not special to custom classes. It is the general answer for generic list deserialization.
Arrays are simpler, but lists are often nicer to work with
If you deserialize into an array first, the type information is easier because arrays preserve component type directly.
This works, but many applications still prefer List<Person> because the collection API is more convenient than arrays for later processing.
Nested generic types use the same idea
If the JSON is more complex, such as List<Map<String, Person>>, the same TypeToken approach still applies. The only difference is that the generic signature becomes more detailed.
The main lesson is that Gson is not the obstacle. The real issue is Java runtime type information for generics.
Validate the incoming JSON shape
One common source of bugs is that the JSON is not actually an array. If the payload is an object containing a field that holds the array, the type token can still be correct while the deserialization fails because the JSON shape does not match the Java target type.
Always make sure:
- array JSON is deserialized into a collection or array type
- object JSON is deserialized into an object type
Type correctness and JSON-shape correctness are separate requirements.
Common Pitfalls
- Trying to use
List<T>.classfails because Java erases generic type parameters at runtime. - Forgetting
TypeTokenfor generic collections makes Gson deserialize with insufficient type information. - Assuming arrays and lists need the same runtime type hint ignores that arrays preserve component type differently.
- Blaming Gson when the real problem is that the JSON payload shape does not match the target Java type.
- Hiding malformed or partial input behind broad exception handling makes deserialization failures much harder to debug.
Summary
- Gson needs explicit runtime type information to deserialize
List<T>correctly. - The standard solution is
new TypeToken<List<T>>() {}.getType(). - This applies to custom classes and simple element types alike.
- Arrays are easier for runtime typing, but lists are often more convenient in application code.
- Always verify that the JSON shape matches the target type as well as the generic parameter.

