0

我有一个 Java 类,它包含有关数据库实体的通用信息(即它们的 id)。

@Data
public class DbEntity {
    protected final String id;

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

我们使用 Lombok@Data来生成 getter toStringequals...

在 Java 中,我会简单地扩展这个类并@Data再次添加。

@Data
class JavaSubClass extends DbEntity {

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

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

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

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. 不要使用数据类。这可行,但让我承担实施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)

正如我所说,我对上面提出的任何解决方案都不满意。使用抽象超类或接口肯定会更合适。但是,Entity 类驻留在主要 Java 项目所依赖的库中。我只是因为新的 Kotlin 依赖而犹豫要更改它。

有没有人遇到过类似的问题并就如何解决这些问题提出建议?

4

1 回答 1

0

作为一种解决方法,在KT-6653 - Kotlin 属性不会覆盖 Java 样式的 getter 和 setter之前,我会选择第 3 点的变体,即:

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

这种变体的好处是,您始终可以访问“原始”getId功能。您不会使用bogusId()-function,因为它不可见/不可访问(通过反射访问它没有意义......您只对实际的id-field 感兴趣)。这对双方都有效并且看起来相似:来自 Java 和 Kotlin。尽管如此,这个变体还是使用了 2 个字段,但在最好的情况下,您将来可以将其替换为以下内容:

data class SubClass(override val id: String, val name : String) : DbEntity(id)
于 2019-10-07T14:41:17.430 回答