Kotlin数据类实现Java接口

Ody*_*eus 27 java overriding kotlin data-class

我正在尝试将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
Run Code Online (Sandbox Code Playgroud)

其中实现了Java接口:

public interface Entity {
   Long getId();  
}
Run Code Online (Sandbox Code Playgroud)

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

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

我是否必须为id param使用任何其他关键字?什么"!" 签名意味着什么?

Ale*_*lov 41

这里的问题是Kotlin首先加载Java类Entity,它将其getId视为一个函数,而不是某些属性的getter.Kotlin类中的属性getter不能覆盖函数,因此该属性id不会被绑定为getId函数的实现.

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

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

  • 从Java的角度来看,在生成的字节码中,它们是相同的。属性获取器被编译为名为“ getXxx”的方法。但是对于Kotlin(1.0.0版),属性访问器和函数是不同的,并且您不能在层次结构中将两者混合使用。 (2认同)