实现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代码的混合层次结构中有些类使用属性和一些函数,那么各种复杂的问题就会出现。签名中的code>表示这是一个platofrm类型,即来自Java的类型。你可以了解更多