javaandroidkotlinparcel

Kotlin android parcelable


I've used auto generated feature of android plugin for android studio and it generated me the following code, but I can't understand why is there need for final val for CREATOR field ? I see final keyword for the first time in kotlin.

data class Person(
        val name: String,
        val surname: String
) : Parcelable {
    constructor(source: Parcel): this(source.readString(), source.readString())

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeString(name)
        dest?.writeString(surname)
    }

    companion object {
        @JvmField final val CREATOR: Parcelable.Creator<Person> = object : Parcelable.Creator<Person> {
            override fun createFromParcel(source: Parcel): Person {
                return Person(source)
            }

            override fun newArray(size: Int): Array<Person?> {
                return arrayOfNulls(size)
            }
        }
    }
}

Solution

  • 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.