Kotlin android parcelable

ash*_*hur 6 java android parcel kotlin

我已经为android studio使用了android插件的自动生成功能,它为我生成了以下代码,但我无法理解为什么需要final valfor CREATORfield?我final在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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Alb*_*lvo 6

在 Kotlin 中,您可以使用@ParcelizeKotlin Android 扩展:

@Parcelize
data class User(val id: String, val name: String) : Parcelable
Run Code Online (Sandbox Code Playgroud)

这是一个编译器插件,可以自动为您生成Parcelable实现。

Kotlin 文档上的此页面提供了有关它的更多详细信息,包括要求、支持的类型以及如何为不受支持的类型创建自定义 parser


如果您很好奇并想深入了解实现的技术细节,请参阅 Kotlin Evolution and Enhancement Process Compiler Extension to Supportandroid.os.Parcelable


此功能在Kotlin 1.3.40 之前实验性的。如果你还在使用早于 1.3.40 的 Kotlin 版本,你需要启用实验性功能才能使用这个:

android {
    // Enable @Parcelize
    // You only need this for Kotlin < 1.3.40
    androidExtensions {
        experimental = true
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)


mie*_*sol 5

在Kotlin 课程中,成员默认为最终成员.换句话说,以下声明具有相同的字节码:

@JvmField final val CREATOR: Parcelable.Creator<Person> = PersonCreator()
@JvmField val CREATOR: Parcelable.Creator<Person> = PersonCreator()
Run Code Online (Sandbox Code Playgroud)

因此,虽然生成的代码具有final关键字并且它不是错误,但它是多余的.

即使类和成员默认是最终的final,Kotlin 仍然需要修饰符.一个例子是将open方法标记为final派生类:

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
}
Run Code Online (Sandbox Code Playgroud)

虽然在java中创建public static字段是一个很好的做法,final没有严格要求将Parccelable.Creator字段标记为:

实现Parcelable接口的类还必须具有一个名为CREATOR的非空静态字段,该字段实现Parcelable.Creator接口.