Kotlin 数据 classes with Java super class

Kotlin data classes with Java super class

我有一个 Java class,其中包含关于数据库实体的一般信息(即它们的 ID)。

@Data
public class DbEntity {
    protected final String id;

    public DbEntity(String id) {
        this.id = id;
    }
}

我们使用 Lombok @Data 生成 getters, toString, equals...

在 Java 中,我将简单地扩展此 class 并再次添加 @Data

@Data
class JavaSubClass extends DbEntity {

    public JavaSubClass(String id) {
        super(id);
    }
}

在较新的服务中,我们使用 Kotlin,但希望重用标准 classes,例如 DbEntity

我的第一种方法是简单地声明一个数据 class 例如

data class SubClass1(val id: String, val name: String) : DbEntity(id)
Accidental override: The following declarations have the same JVM signature (getId()Ljava/lang/String;):
  fun <get-id>(): String defined in com.demo.SubClass1
  fun getId(): String! defined in com.demo.SubClass1

经过一番阅读后,我找到了几个解决方案,但我都不是很满意。

  1. 不要使用数据 classes。这行得通,但留给我的任务是实施 equals
class SubClass4(id: String, val name: String) : DbEntity(id)
  1. 复制字段。这可行,但我们最终得到两个可能不同步的字段。
data class SubClass3(val subId: String, val name: String) : DbEntity(subId)
  1. 为 getter 指定一个不同的名称。这从根本上也复制了该字段,但隐藏了 getter.
data class SubClass2(@get:JvmName("getId_") val id: String, val name: String) : DbEntity(id)

正如我所说,我对上面提出的任何解决方案都不满意。有一个抽象的 super class 或一个接口肯定会更合适。但是,实体 class 驻留在主要 Java 项目所依赖的库中。由于新的 Kotlin 依赖项,我犹豫要不要更改它。

有没有人遇到过类似的问题并且有解决方法的建议?

作为解决方法,在 KT-6653 - Kotlin properties do not override Java-style getters and setters 修复之前,我会采用您的第 3 点的变体,即:

data class SubClass(@get:JvmName("bogusId") private val id: String, val name: String) : DbEntity(id)

此变体的好处是,您始终可以访问 "original" getId 功能。您不会使用 bogusId()-函数,因为它不是 visible/accessible(通过反射访问它没有任何意义……您只对实际的 id-字段感兴趣)。这对双方都有效并且看起来相似:来自 Java 以及来自 Kotlin。尽管如此,在幕后这个变体使用了 2 个字段,但在最好的情况下,您可以在将来用类似的东西替换它:

data class SubClass(override val id: String, val name : String) : DbEntity(id)