实现Java接口的Kotlin数据类

实现Java接口的Kotlin数据类,java,overriding,kotlin,data-class,Java,Overriding,Kotlin,Data Class,我想把科特林介绍到我目前的项目中。我决定从实体开始,它似乎完美地映射到数据类。 例如,我有一个数据类: 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? = nu

我想把科特林介绍到我目前的项目中。我决定从实体开始,它似乎完美地映射到数据类。 例如,我有一个数据类:

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();  
}
但由于某些原因,编译器不理解该方法已经实现:

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


id参数是否需要使用其他关键字?签名中的“!”是什么意思?

这里的问题是Kotlin首先加载Java类
实体
,并且它将
getId
视为一个函数,而不是某个属性的getter。Kotlin类中的属性getter无法重写函数,因此属性
id
未绑定为
getId
函数的实现

为了解决这个问题,您应该重写Kotlin类中的原始函数
getId
。这样做将导致新函数和字节码中的
id
的getter之间的JVM签名冲突,因此还应通过使属性
私有来防止编译器生成getter:

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

    ...
}

请注意,这个答案是从这里改编的:

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

--编辑--
亚历山大打败了我!不管怎样,他的答案更好!;)

回答得好!还有一件事:这是否意味着getter/setter不是Java中的常规方法?在生成的字节码中,从Java的角度来看,它们是相同的。属性getter被编译为名为
getXxx
的方法。但是对于Kotlin(1.0.0版),属性访问器和函数是不同的,您不能在层次结构中混合使用这两个。是否讨论过如何更改这一点?有什么原因不应该这样做吗?有。其中一个问题是,在Kotlin中,不能用
fun getX
覆盖
val x
,反之亦然(通过设计),因此,如果Kotlin和Java代码的混合层次结构中有些类使用属性和一些函数,那么各种复杂的问题就会出现。
表示这是一个platofrm类型,即来自Java的类型。你可以了解更多