Explain Codes LogoExplain Codes Logo

Gson - convert from Json to a typed ArrayList<T>

java
type-token
gson
deserialization
Anton ShumikhinbyAnton Shumikhin·Oct 13, 2024
TLDR

The go-to mechanism to deserialize a JSON array into an ArrayList<T> with Gson involves the classy TypeToken. TypeToken does the magic of preserving generic type information at runtime in lieu of Java's type erasure.

import com.google.gson.reflect.TypeToken; import com.google.gson.Gson; import java.util.ArrayList; String json = "[{\"key\": \"value\"}]"; // JSON party starts here ArrayList<MyType> list = new Gson().fromJson(json, new TypeToken<ArrayList<MyType>>(){}.getType());

Just replace MyType with the Classy McClassface you want to summon from the JSON array, and oops, you've got an ArrayList full of your classy instances.

Defeating type erasure with TypeToken

Java's unlike to remember anything about the generic types at runtime, known as type erasure. It's annoying when you want to convert a JSON string into a generic ArrayList<T>. TypeToken to the rescue! It helps you capture that amnesiac type information:

Type listType = new TypeToken<ArrayList<MyType>>(){}.getType(); // Gotcha, Type! ArrayList<MyType> myTypeList = gson.fromJson(jsonArray, listType); // Here comes your list

By creating an anonymous subclass of TypeToken, we secure a Type that represents ArrayList<MyType>. Pretty neat, huh?

Unraveling pitfalls and their remedies

While TypeToken is the Jason Bourne of generified deserialization, there are some spyware traps to be careful about:

  1. Wildcard Generics: TypeToken can't really handle wildcard generic types (ArrayList<?>). For such mysterious cases, you either bind the wildcard to a known type or live wildly with raw types.

  2. Array Conversion Shortcut: An alternative to migrate JSON array to JsonLog[], take this shorter path:

JsonLog[] array = gson.fromJson(json, JsonLog[].class); // Convert and avoirdupois ArrayList<JsonLog> list = new ArrayList<>(Arrays.asList(array)); // Mind the Array, step into List
  1. Kotlin Spicing: Kotlin's got some different seasoning for TypeToken. So, if you're on Kotlin street, reify those type parameters:
inline fun <reified T> Gson.fromJson(json: String): T = this.fromJson(json, object: TypeToken<T>() {}.type) // Look, I Kotlin-ed!

Optimizing Gson with some proven wisdom

Efficiency isn't overrated, especially when you are grappling with big data or tight performance goals. So, here are some Fahrenheit-451 temperature tips for you:

  • Minimalist Data Classes: The more your data classes mirror your JSON structure, the more you'll sleep at night. Keep them tight, trim, and matching to avoid unnecessary tortuous nightmares during deserialization.

  • GsonBuilder for Custom Configurations: Pull up GsonBuilder for custom job-configurations. Setting date formats or playing with naming policies come handy:

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create(); // Hot off the builder oven
  • SharedPreferences Storage: For the Android kids, a tip. Storing ArrayList in SharedPreferences? Convert the list to/out from JSON using toJson and fromJson.

Mastering the art of storage and retrieval

When persistence storage or data sharing keeps you awake at night, turn your ArrayList into a JSON string:

String listJson = new Gson().toJson(myTypeList); // The JSON avatar of your list

To retrieve your ArrayList in broad Java daylight:

ArrayList<MyType> retrievedList = new Gson().fromJson(listJson, new TypeToken<ArrayList<MyType>>() {}.getType()); // Welcome back!