AutoValue is immensely helpful for us Android folks who like immutability and cutting down on boilerplate (getters, setters, Parcelable generation and more!). Put in an different way, it makes up for Java not having first-class support for value types.

Like everyone else, I have been playing with Kotlin for sometime now and been converting code from Java to Kotlin file-by-file. While converting AutoValue Java classes, I’ve realised it doesn’t make a lot of sense to continue to use AutoValue, as Kotlin’s data classes let you do pretty much all that things that former does with value types.

So I started giving a shot at migrating from AutoValue to data classes. Turns out it isn’t that easy, especially if you’re using a library like Gson for object mapping.

My current setup includes: AutoValue + Gson + AutoValue-Gson. The latter for generating Gson TypeAdapters at compile time, so that it doesn’t have to use reflection to create objects. This is advantageous if you’re using Proguard to obfuscate your code or have heavy objects being serialized/deserialized.

There’s not one, but three ways to approach this issue:

1. Let Gson’s ReflectiveTypeAdapter take care of the data classes

No-arguments constructor is the default hook for Gson to construct objects. Though, you’d be surprised to see that Gson works out of the box with data classes — even the ones without default values, by using sun.misc.Unsafe.

sun.misc.Unsafe is the dark side of java, letting you do shady things like construct objects without invoking their constructor, and more. So you’d want to stay away from it.

With Unsafe out of the way, you can try:

Explicit no-args secondary constructor in data classes Implicit no-args primary constructor with default values for all properties

Pros: No new dependencies!

Cons: Data classes can be verbose with default values and secondary no-args constructors.

2. Migrate to Moshi, AutoValue-Moshi and Kotshi

Moshi is like Gson v3.0 — modern, smaller, and also better in performance, if you already use other OK libraries.

For generating type adapters for data classes, you can use Kotshi. But you’ll also need AutoValue-Moshi for Java classes, as you’re only going to incrementally convert them into Kotlin.

Pros: No reflection means, this plays well with Proguard and might be better in performance. Also, no ugly default constructors!

Cons: Migration from Gson to Moshi might not be that easy — if you’re using Gson features which do not have a Moshi counterpart, like field naming policy etc.

3. Use GsonValue instead of AutoValue-Gson

This library is for type adapters generation as well, but it works with both AutoValue classes and data classes.

There’s one caveat though: unlike AutoValue-Gson, it needs you to write a static factory method for every AutoValue class. This was a pain in our case, as we had static factories defined only where there was a usecase to create object manually. (as opposed to deserialized from JSON)

Pros: No need to migrate to Moshi (and companion libraries).

Cons: API is quite different from AutoValue-Gson and can result in needing unnecessary verbose static factories for AutoValue classes.

Whichever method you go for, have fun increasing Kotlin percentage in your codebase!