如何适应实体 class 的不同参数

How to accomodate different arguments for entity class

我在 if/else-if 语句中针对 2 个不同的条件调用我的实体 class,我传递给参数的值取决于条件。在 if 块中,我传递了 3 个参数,在 else-if 块中,我传递了 4 个参数。实体的对象抛出错误,因为它需要 4 个参数。我希望第一个参数是可选的,我想知道在 Kotlin 中是否有办法做到这一点。

这是我的实体class:

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    var id: Int? = null, 

    val username: String? = null, 
    val hint: String? = null, 
    val password: String? = null)

这是我将值插入实体对象的 if/else-if 块:

if (requestCode == ADD_ENTRY_REQUEST && resultCode == Activity.RESULT_OK) {
            ...

            val entry = Entry(username, hint, password)
            ...

        } else if (requestCode == EDIT_ENTRY_REQUEST && resultCode == Activity.RESULT_OK) {
            ...

            val entry = Entry(id, username, hint, password)
            ...

        }

在 Java 中,您可以通过创建 2 个参数数量匹配的构造函数来解决这个问题,但我想知道我们是否可以在 Kotlin 中做同样的事情,或者是否有不同的方法。

你可以试试把id移到最后,像这样:

@Entity(tableName = "entry_table")
data class Entry(
    val username: String? = null, 
    val hint: String? = null, 
    val password: String? = null,
    @PrimaryKey(autoGenerate = true) 
    var id: Int? = null)

然后像这样创建它:

val entry = Entry(username, hint, password, id)

或者,如果您想将 id 作为第一个参数,您可以使用这样的命名参数:

val entry = Entry(username = username, hint = hint, password = password)

希望对您有所帮助!

您可以而且可能应该使用多个构造函数。

您的方法的缺点是出于技术原因,所有属性都必须是可选的。但我想,usernamepassword 实际上是强制性的。后果是编译时检查丢失(因此容易出现 NPE)和阅读麻烦(访问用户名时需要!!)。

您可以按照以下方法避免这些问题:

  1. 要使您的 class 具有 JPA 所需的默认 no-arg 构造函数,请使用编译器插件 https://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support
  2. 设置强制属性non-nullable(我假设,只有hint是可选的)
  3. 使用任意数量的辅助构造函数

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    val id: Int, 

    val username: String,
    val hint: String?, 
    val password: String
) {
    constructor(
        username: String,
        hint: String = null,
        password: String = "change it"
    ) : this(0, username, hint, password)
}

在更现实的情况下,只有 idusername 是不可变的。 passwordhint 应该允许更改。

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    val id: Int, 
    val username: String
) {
    constructor(
        username: String,
    ) : this(0, username)

    var hint: String? = null
    var password: String = "change it"
}