Why converting Autovalue class to Kotlin data class may not be “pragmatic” for JSON models at this moment

  • The value classes represents JSON fetched from backend server. I don’t create the object myself. It is done via retrofit and gson so I don’t need extra builder declarations (which can be cumbersome to maintain too)
  • I need Parcelable implementation.
  • I cannot commit to 100% kotlin.
  • I don’t want to write any extra code (type adapters, parcelable fields) for my value classes.

A sample value class in AutoValue:

@AutoValue
public abstract class JavaPerson implements Parcelable {
@NonNull
public abstract String name();
public abstract int age(); @NonNull
public abstract String job();
@NonNull
public static TypeAdapter<JavaPerson> typeAdapter(
@NonNull Gson gson) {
return new AutoValue_JavaPerson.GsonTypeAdapter(gson);
}
}

The equivalent data class in Kotlin

data class Person(val name: String, val age: Int, val job: String)

Parcelable for data class

  1. Parcelable Code Generator — It’s a IntelliJ plugin that generates necessary parcelable fields and methods. It works great, but the generated code lives in your codebase and becomes something you have to maintain. (the same argument that Hadi Hariri gives to IDE plugins for Java pojo)
  2. PaperParcel — A annotation processor available for data classes. It eliminates “some” boilerplate code when implementing Parcelable interface.
@PaperParcel
data class User(
val id: Long,
val firstName: String,
val lastName: String
) : Parcelable {
companion object {
@JvmField val CREATOR = PaperParcelUser.CREATOR
}
override fun describeContents() = 0override fun writeToParcel(dest: Parcel, flags: Int) {
PaperParcelUser.writeToParcel(this, dest, flags)
}
}
@PaperParcel
data class User(
val id: Long,
val firstName: String,
val lastName: String
) : PaperParcelable {
companion object {
@JvmField val CREATOR = PaperParcelUser.CREATOR
}
}

JSON deserialization for data class

fun main(args: Array<String>) {val json = """{"name": "Eric", "age": 32, "job": null}"""val gsonPerson: Person = Gson().fromJson(json, Person::class.java)
println("GSON -> $gsonPerson")
}
data class Person(val name: String, val age: Int, val job: String)
GSON -> Person(name=Eric, age=32, job=null)
// job should be a non-null property!
  • Write your own TypeAdapters, but this becomes a lot of code and write and maintain
  • Use Moshi or Jackson with their kotlin-module, but again they both use kotlin reflection to access property information. It's something you do not need when using AutoValue.

Conclusion

  • An Android platform specific code generation (by Google and Jetbrains) for parcelable fields since data class is a built-in language, not a library we can easily tweak or fork.
  • An annotation processor that generates type adapters for data classes just like auto-value-gson.
  • Some “creative ways” from Square engineers (I believe they can as they always do!)

--

--

--

Honest Android developer. Loves Kotlin and new technologies.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Eric Lin

Eric Lin

Honest Android developer. Loves Kotlin and new technologies.

More from Medium

Introduction

John Wilkes Booth’s Brother Saved the Life of Abraham Lincoln’s son

John Wilkes Booth's Brother Saved the Life of Abraham Lincoln's son

UNTIL THEY ALL FALL

The Arrest of Mohammad Zubair (Alt News)