Kotlin android parcelable

In Kotlin classes and members are final by default. In other words the following declarations have the same bytecode:

@JvmField final val CREATOR: Parcelable.Creator<Person> = PersonCreator()
@JvmField val CREATOR: Parcelable.Creator<Person> = PersonCreator()

So while the generated code has final keyword and it is not an error it is redundant.

Even though classes and members are final by default there are still a need for final modifier in Kotlin. One example would be to mark open method as final in derived class:

open class Base {
    open fun test(){}
}

open class DerivedA : Base(){
    final override fun test(){}
}

class DerivedB : DerivedA() {
    override fun test(){} //error: 'test' in 'DerivedA' is final and cannot be overriden
}

While it's a good practice to make public static field final in java there's no strict requirement for the Parccelable.Creator field to be marked as such:

Classes implementing the Parcelable interface must also have a non-null static field called CREATOR of a type that implements the Parcelable.Creator interface.


In Kotlin you can use the @Parcelize Kotlin Android Extension:

@Parcelize
data class User(val id: String, val name: String) : Parcelable

This is a compiler plugin that automatically generates the Parcelable implementation for you.

This page on the Kotlin docs gives more details about it, including requirements, supported types and how to create custom parcelers for unsupported types.


If you are curious and you want dive into the technical details of the implementation, see the Kotlin Evolution and Enhancement Process Compiler Extension to Support android.os.Parcelable.


This feature was experimental until Kotlin 1.3.40. If you are still using a Kotlin version earlier than 1.3.40, you need to enable the experimental features to use this:

android {
    // Enable @Parcelize
    // You only need this for Kotlin < 1.3.40
    androidExtensions {
        experimental = true
    }
    ...
}