是否可以更改为Kotlin数据类生成的toString()方法的行为?

时间:2019-02-06 09:59:10

标签: java kotlin lombok

例如:

data class Key(
    val id:          Int,
    val secret:      String,
    val description: String?
)

要排除或屏蔽密码或信用卡号之类的特殊属性,请执行以下操作:

Key(
    id          = 1,
    secret      = "foo",
    description = "bar"
).toString()
// Key(id=1, description=bar)
// or
// Key(id=1, secret=********, description=bar)

或者忽略带有null的属性以使结果字符串更具可读性:

Key(
    id          = ...,
    secret      = ...,
    description = null
).toString()
// Key(id=...)
// or
// Key(id=..., secret=...)

每次执行toString()可能非常繁琐且容易出错,尤其是在类中的属性太多的情况下。

该问题是否有(即将推出的)解决方案(例如,针对Java的Lombok)?

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

data class Key(val id: Int, val secret: String, val description: String?){ 
    override fun toString() = kotlinToString(properties = arrayOf(Key::id, Key::description)
} 

示例输出:

答案 1 :(得分:0)

我对Andrii Vdovychenko的先前回复进行了如下修改:

data class Key(val id: Int, val secret: String, val description: String?){
    override fun toString() = kotlinToString(target = this, properties = arrayOf(prop(Key::id), prop(Key::description), prop(Key::secret)))
}

fun <T>prop(kp : KProperty1<T, Any?>) : KProperty1<Any, Any?> {
    return kp as KProperty1<Any, Any?>
}

fun kotlinToString(target: Any, properties : Array<KProperty1<Any, Any?>>) : String {
    return properties
            .map { kp -> Pair(kp.name, kp.get(target)) }
            .filter { p -> p.second != null }
            .map { p -> "${p.first}: ${p.second}" }
            .joinToString(", ")
}

您可以使用以下main函数测试mi的实现:

fun main(args : Array<String>) {
    println(Key(1, "aa", "bbb").toString())
    println(Key(1, "aa", null).toString())
}

哪个输出是

id: 1, description: bbb, secret: aa
id: 1, secret: aa

也许您可以更改kotlinToString的实现,以便在输出字符串中包含一个 per-class 前缀,也许将其作为参数传递给kotlinToString,但我希望这可以帮助您!