Gson
Deserialization
Java
JSON
Programming

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:

java
// Not valid generic type information for Gson
// List<Person> people = gson.fromJson(json, List<Person>.class);

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.

java
1import com.google.gson.Gson;
2import com.google.gson.reflect.TypeToken;
3import java.lang.reflect.Type;
4import java.util.List;
5
6class Person {
7    String name;
8    int age;
9}
10
11public class Main {
12    public static void main(String[] args) {
13        String json = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Jane\",\"age\":25}]";
14
15        Gson gson = new Gson();
16        Type listType = new TypeToken<List<Person>>() {}.getType();
17        List<Person> people = gson.fromJson(json, listType);
18
19        for (Person person : people) {
20            System.out.println(person.name + " " + person.age);
21        }
22    }
23}

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.

java
1import com.google.gson.Gson;
2import com.google.gson.reflect.TypeToken;
3import java.lang.reflect.Type;
4import java.util.List;
5
6public class Main {
7    public static void main(String[] args) {
8        String json = "[\"red\",\"green\",\"blue\"]";
9
10        Gson gson = new Gson();
11        Type type = new TypeToken<List<String>>() {}.getType();
12        List<String> colors = gson.fromJson(json, type);
13
14        System.out.println(colors);
15    }
16}

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.

java
1import com.google.gson.Gson;
2
3class Person {
4    String name;
5    int age;
6}
7
8public class Main {
9    public static void main(String[] args) {
10        String json = "[{\"name\":\"John\",\"age\":30}]";
11        Gson gson = new Gson();
12        Person[] people = gson.fromJson(json, Person[].class);
13        System.out.println(people[0].name);
14    }
15}

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>.class fails because Java erases generic type parameters at runtime.
  • Forgetting TypeToken for 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.

Course illustration
Course illustration

All Rights Reserved.