情况:
我有一个包含lateinit
字段的类,因此它们不在构造函数中:
class ConfirmRequest() {
lateinit var playerId: String
}
我想在所有字段中使用toString()
方法并且不想手动编写,以避免打印锅炉。在Java中,我使用 Lombok @ToString
注释来解决这个问题。
问题:
有没有办法在Kotlin中实现它?
答案 0 :(得分:10)
推荐的方法是手动编写toString
(或由IDE生成),并希望你没有太多这样的类。
data class
的目的是容纳最常见的85%的案例,其中15%留给其他解决方案。
答案 1 :(得分:8)
和你一样,我习惯在Java中使用lombok for toString()
和equals()
,所以有点失望的是Kotlin中的非数据类需要所有的标准样板。
所以我创建了Kassava,这是一个开源库,可让您实现toString()
和equals()
而无需任何样板 - 只需提供属性列表即可完成!< / p>
例如:
// 1. Import extension functions
import au.com.console.kassava.kotlinEquals
import au.com.console.kassava.kotlinToString
import java.util.Objects
class Employee(val name: String, val age: Int? = null) {
// 2. Optionally define your properties for equals()/toString() in a companion
// object (Kotlin will generate less KProperty classes, and you won't have
// array creation for every method call)
companion object {
private val properties = arrayOf(Employee::name, Employee::age)
}
// 3. Implement equals() by supplying the list of properties to be included
override fun equals(other: Any?) = kotlinEquals(
other = other,
properties = properties
)
// 4. Implement toString() by supplying the list of properties to be included
override fun toString() = kotlinToString(properties = properties)
// 5. Implement hashCode() because you're awesome and know what you're doing ;)
override fun hashCode() = Objects.hash(name, age)
}
答案 2 :(得分:8)
我发现Apache Commons Lang的"InconsistentNaming"
反射很有用,但是当我不需要时,它会调用Rules.ReSharper
和其他方法(以及一个名为ToStringBuilder
的方法来自第三方lib生成NPE)。
所以我跟着:
hashCode()
答案 3 :(得分:1)
您可以定义一个包含您要使用的数据的数据类,并通过委托给它来实现方法。
答案 4 :(得分:0)
使用Kotlin反射怎么样?我在科特林呆了几天,如果我误解了问题或写了“科特林效率低下”的例子,我深表歉意。
override fun toString() : String{
var ret : String = ""
for (memberProperty in this.javaClass.kotlin.memberProperties){
ret += ("Property:${memberProperty.name} value:${memberProperty.get(this).toString()}\n");
}
return ret
}
这也可以在新创建的接口中实现,例如toString2Interface作为ToString2Interface。然后所有实现ToString2Interface的类都将具有toString2()
答案 5 :(得分:0)
这就是我最终要做的。
在Any
类上创建扩展功能
fun Any.toStringByReflection(exclude: List<String> = listOf(), mask: List<String> = listOf()): String {
val propsString = this::class.memberProperties
.filter { exclude.isEmpty() || !exclude.contains(it.name) }
.joinToString(", ") {
val value = if (!mask.isEmpty() && mask.contains(it.name)) "****" else it.getter.call(this).toString()
"${it.name}=${value}"
};
return "${this::class.simpleName} [${propsString}]"
}
然后您可以从单个类型调用此方法。
override fun toString(): String {
return this.toStringByReflection()
}
它在下面生成字符串
Table [colums=[], name=pg_aggregate_fnoid_index, schema=pg_catalog, type=SYSTEM INDEX]
名称字段被屏蔽:
override fun toString(): String {
return this.toStringByReflection(mask= listOf("name"))
}
它生成
Table [colums=[], name=****, schema=pg_catalog, type=SYSTEM INDEX]