33

我正在尝试将 Kotlin 引入我当前的项目中。我决定从实体开始,它似乎完美地映射到数据类。例如我有一个数据类:

data class Video(val id: Long, val ownerId: Long, val title: String, val description: String? = null,
             val imgLink: String? = null, val created: Date? = null, val accessKey: String? = null,
             val views: Long? = null, val comments: Long? = null, val videoLink: String? = null): Entity

其中实现了Java接口:

public interface Entity {
   Long getId();  
}

但由于某种原因,编译器不理解该方法已经实现:

“视频”类必须声明为抽象或实现抽象成员 public abstract fun getId(): kotlin.Long!在 net.alfad.data.Entity 中定义

我是否必须为 id 参数使用任何其他关键字?"!" 是什么意思 在签名中是什么意思?

4

2 回答 2

50

这里的问题是 KotlinEntity首先加载 Java 类,它被getId视为一个函数,而不是某个属性的 getter。Kotlin 类中的属性 getter 无法覆盖函数,因此该属性id未绑定为getId函数的实现。

要解决此问题,您应该覆盖 Kotlin 类中的原始函数getId。这样做会导致新函数和字节码中的 getter 之间的 JVM 签名冲突id,因此您还应该通过设置属性来防止编译器生成 getter private

data class Video(
    private val id: Long,
    ...
): Entity {
    override fun getId() = id

    ...
}

请注意,此答案已从此处改编:https ://stackoverflow.com/a/32971284/288456

于 2016-02-25T15:40:54.300 回答
1

如果这是您的整个数据类,那么您不会覆盖 getId()。我看到您有一个名为 id 的属性,Kotlin 应该为此生成一个 getter,但不会用您需要指示您正在覆盖抽象函数的 override 关键字标记。

-- 编辑 -- 亚历山大打败了我!反正他的回答更好!;)

于 2016-02-25T15:41:18.727 回答