This page looks best with JavaScript enabled

Android: Handle generics using Gson in both Kotlin and Java

 ·  ☕ 4 min read  ·  ✍️ Iskander Samatov

If you’re working on real-world projects you will come across this problem all the time - you need to create some kind of utility method that converts your JSON strings into Kotlin or Java objects or collections of objects. In this post, I will show you how to do that using Gson.

Nowadays a lot of people use Gson to convert JSON strings to Java or Kotlin objects and in this tutorial I will show you how to write convenience methods that will make that task easier.

As promised I will show you an example in both Kotlin and Java languages. I will start with Kotlin solution, since it’s shorter and more elegant. If you’re looking for Java solution you can skip to the Java section.

Dependencies

First things first, you need to make sure you have the necessary dependencies to get the examples working:

implementation 'com.google.code.gson:gson:2.8.5'

Note: current version might be different for you, you can double check it here.

Gson for Kotlin

Method implementation

First thing you need to do is create a Kotlin utility class, if you don’t already have one. For example you can call it Serializer.

Declare a companion inside of the class . companion makes all methods inside of it static. You can read more about it here . Afterwards, insert this method inside of your companion:

1
2
3
inline fun fromJson(json: String): T {
   return Gson().fromJson(json, object: TypeToken(){}.type)
}

The method uses Gson().fromJson function under the hood. Further important things to note:

  • We use inline function with reified keyword to prevent type erasure, because Kotlin performs it at a runtime by default.
  • T is a generic type which will be inferred from the call when you use the method. Hence you don’t need to explicitly pass type parameter to it.
  • TypeToken is where the magic happens. It’s used to tell Gson what exactly you want your string to get converted to. This stackoverflow answer helped me understand TypeToken and its usage better.
  • object: is used in Kotlin to instantiate anonymous class instances which extend from the parent class. In other words, this part object: TypeToken(){} actually creates an anonymous class that is a child of TypeToken class.

Usage

As a result, you can make a simple call like this to convert you JSON string into any Kotlin class or a collection of classes:

1
val mPosts: List = Serializer.fromJson(postsStr)

This solution is very elegant and flexible, and you can use it to convert JSON strings to anything from a single custom object to a collection of the custom objects as show in the example above. As long as the structure of the object matches the structure of the JSON string.

However, one drawback of this implementation is that you can’t use it in Java, since inline function cannot be called from Java code. Therefore if you have mixed projects you need to keep that in mind.

Gson for Java

Java solution is less elegant but you can still achieve a lot flexibility with it.

First of all, converting JSON string into a single instance of the Java object can be done by simply providing class parameter to Gson().toJson method:

1
2
3
4
5
6
7
public static  T toObject(String jsonStr, Class cls) {
    if (jsonStr == null)
        return null;
    Gson gson = new Gson();

    return gson.fromJson(jsonStr, cls);
}

However, to convert JSON into a collection of Java objects I recommend using TypeToken.getParameterized method:

1
2
3
4
5
public static  Map toMapOfObjects(String json, Class cls) {
    Map classMap = new Gson()
            .fromJson(json, TypeToken.getParameterized(HashMap.class, String.class, cls).getType());
    return classMap;
}

Above is an implementation of the utility method which converts JSON string into a map of custom Java objects.

Unfortunately, with collections you can’t simply provide parameterized class like so: Map<T>.class That’s just not how things work in Java, hence TypeToken.getParameterized can help us solve that problem.

First parameter is always the collection type class, in this case HashMap.class. Secondly, we provide the type class of the objects stored in the collection. We provide String.class because we use string as a key and cls as a value type for our map.

However, the number of parameter passed to TypeToken.getParameterized doesn’t have to be strictly 3. It depends on the type of the collection:

1
2
3
4
5
6
public static > List> toListOfObjects(String jsonArray, Class> cls) {
    List> list = new Gson()
            .fromJson(jsonArray, TypeToken.getParameterized(List.class, cls).getType());

    return list;
}

For example, here we only specify 2 parameters:

  • Collection type parameter — List.class
  • The type parameter of our custom Java object

And that’s all for this tutorial, I hope you found my explanation useful. Let me know if you have any questions or suggestions.

If you’d like to get more web development, React and TypeScript tips consider following me on Twitter, where I share things as I learn them.
Happy coding!

Share on

Software Development Tutorials
WRITTEN BY
Iskander Samatov
The best up-to-date tutorials on React, JavaScript and web development.