【问题标题】:Kotlin: Multiple named companion objectsKotlin:多个命名的伴随对象
【发布时间】:2019-11-06 08:26:13
【问题描述】:

我有一个类同时包含java.io.Serializableandroid.os.Parcelable。 这些类需要以下伴随对象:

companion object CREATOR : Parcelable.Creator<MyClass> {
    override fun createFromParcel(parcel: Parcel): MyClass
    ...
}

companion object {
    private val serialVersionUid: Long = 123
}

问题是我不能同时拥有这两个伴随对象,因为这会导致only one companion object per class 异常。

如何在同一个类中拥有两个名称不同的伴生对象?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    您可能误解了 Java 示例。

    public static Parcelable.Creator<SDFileDir> CREATOR = ...;
    public static long serialVersionUid = 123;
    

    在 Java 中 - 是的,它是分离的静态对象。您可以在类中放置任意数量的静态字段。

    在 Kotlin 中应该只有一个静态对象(这里称为 Companion)。但这就像这里的一堂课。所以所有新的静态字段都应该在里面。

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<SDFileDir> = ...
        val serialVersionUid: Long = 123
    }
    

    还有一件事:注解@JvmField 可以正确使用Java。

    【讨论】:

    • companion object CREATOR: ... { ... }companion object { val CREATOR = ... } 相同吗?
    • 不,不是。在您的第一个示例中,您将名称和父类设置为伴随对象。我不确定它是否可以从 Java 访问。第二个可以用MyClass.Companion.CREATOR在Java中使用。
    • 在第一种情况下,MyClass.CREATOR 可以从 Java 访问它。
    【解决方案2】:

    事实上,kotlin 中的伴生对象并不对应于 Java 中的静态对象,它们只是共享相似的功能。

    在 Java 中,只涉及两个概念:类及其静态对象。

    在 Koltin 中,我们处理三个概念:类、伴生对象和伴生对象的属性。

    我们访问伴生对象的属性的方式和Java中访问静态对象是一样的,但是在Kotlin中,类和内部属性之间多了一层,就是伴生对象。

    在您的情况下,您要求的不是两个伴随对象,而是一个伴随对象的两个属性,因此只需将这两个属性放在一个伴随对象中即可。

    【讨论】:

      【解决方案3】:

      我可以针对这个问题提出两种解决方案:

      1. 正如@Ircover 所说-您可以在您的常量旁边的companion object 中声明CREATOR(在Java 中只是一个static 字段),但是您需要使用@JvmField 注释来标记按预期工作(因为它是从 Java 中调用的)..
      2. 您不一定需要 companion object 作为常量值,它(在您的情况下不适用于 serialVersionUid,因为它必须在 Java 序列化的类中工作)可以移动到单独的object,到另一个类的companion object,甚至在任何.kt 文件主体内(在类外)..

      【讨论】:

      • 如何在单独的对象中声明 serialVersionUid? Java 序列化库要求该字段位于对象内部。
      猜你喜欢
      • 2016-05-21
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      相关资源
      最近更新 更多