如何使用Java Date对象使Kotlin中的数据类不可变?

时间:2017-10-14 10:14:43

标签: date kotlin immutability kotlin-interop

java.util.Date本身是一个可变对象。因此,即使Kotlin数据类(日期字段声明为val)阻止我更改引用,我也可以修改日期对象本身以更改其值。

我能想出的方法:

使用普通类,覆盖getter和setter。在每次使用克隆方法来制作给定日期的副本。

    @Column(name = "db_date")
    private var dbDate: Date? = null
    get() = dbDate?.clone() as Date
    set(date) {
        field = date?.clone() as Date
    }

此外,我无法使用数据类的copy方法,因为这些类是hibernate实体。所以我需要通过setter修改它们。

我想为我的实体使用数据类的原因是默认情况下这些实现equalshashcode。我们一直在java中使用lombok,现在令人信服的团队创建这些方法很难。即使IDE发生了它,它仍然会被检查到源代码控制中。

那么我有什么办法可以在数据类逻辑上做自定义setter。或者我可以为普通类生成equals和hashcode,而无需在源代码管理中检查它们吗?

编辑:在评论中指出使用java.time.Instant是不可变的。我面临的问题是,这是一个 Hibernate Entity Class ,我们正在使用 hibernate 3.6 。 hibernate 5.2提供了即时支持,因此我们落后了,迁移hibernate将是一项艰巨的任务。我注意到的是kotlin数据类确实以不同的方式允许setter和getter。代码如下:

@Entity
@Table(name = "my_table")
data class MyTable(
    @Id
    @Column(name = "id")
    var id: Long? = null,


    @Column(name = "my_date")
    private var date: Date? = null,


) {
    fun getDate():Date = gradedDate?.clone() as Date
    fun setDate(date: Date?) {
        this.date = date?.clone() as Date
    }
}

2 个答案:

答案 0 :(得分:0)

您可以通过一些技巧来做到这一点:     

@Entity
@Table(name = "my_table")
data class DateWrapper(

        @Id
        @Column(name = "id")
        val id: Long?,

        @Column(name = "my_date")
        private var _date: Date?
) {

    init {
        _date = _date?.clone() as Date
    }

    val date = _date
}

答案 1 :(得分:0)

尝试改用java.sql.Date