GSON Serializing and Deserializing Generic Types

This example shows how to serialize and deserialize a generic class using GSON. Generic type information is lost while serializing because of Java Type Erasure. You can solve this problem by specifying the correct parameterized type for your generic type. Gson provides this with the TypeToken class. Lets see how this works.

Suppose we have an Animal class with a parameterized type.

package com.memorynotfound.json;

public class Animal {

    private T animal;

    public T getAnimal() {
        return animal;
    }

    public void setAnimal(T animal) {
        this.animal = animal;
    }
}

We’ll use the Dog as the parameterized type of Animal.

package com.memorynotfound.json;

public class Dog {

    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Serializing the generic type is not a problem. But when we have to deserialize the generic type, you don’t have the type information because it is lost on serialization. You can solve this problem by specifying the correct parameterized type for your generic type by using the TypeToken, as we see in the following code.

package com.memorynotfound.json;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.Date;

public class GenericType {

    public static void main(String... args){

        Gson gson = new GsonBuilder().create();

        Animal animal = new Animal();
        Dog dog = new Dog("puppy");
        animal.setAnimal(dog);

        String json = gson.toJson(animal);
        System.out.println(json);

        Animal animal1 = gson.fromJson(json, Animal.class);
        System.out.println(animal1.getAnimal().getClass());

        Type animalType = new TypeToken>(){}.getType();
        Animal animal2 = gson.fromJson(json, animalType);
        System.out.println(animal2.getAnimal().getClass());
    }
}
The idiom used to get animalType actually defines an anonymous local inner class containing a method getType() that returns the fully parameterized type.

The previous code generates the following output. Note when you don’t specify the animalType, the deserialization process could not convert it to it’s generic type.

{"animal":{"name":"puppy"}}
class com.google.gson.internal.LinkedTreeMap
class com.memorynotfound.json.Dog

You may also like...