Kotlin - 为非数据类生成toString()

awf*_*fun 24 java tostring kotlin

情况:

我有一个带有lateinit字段的类,因此它们不在构造函数中:

class ConfirmRequest() {
    lateinit var playerId: String
}
Run Code Online (Sandbox Code Playgroud)

我想要一个toString()包含所有字段的方法,并且不想手动编写,以避免锅炉打印.在Java中,我会使用Lombok @ToString注释来解决这个问题.

题:

有没有办法在Kotlin中实现它?

vod*_*dan 10

建议的方法是toString手动编写(或由IDE生成),并希望您没有太多这样的类.

目的data class是容纳85%的最常见情况,其他解决方案留下15%.

  • 最后决定使用允许使用参数构造函数的`jackson-module-kotlin`,因此数据类现在适合我的需要:`data class ConfirmRequest(var playerId:String)` (3认同)

Jam*_*ett 8

和你一样,我习惯使用lombok toString()equals()Java,所以有点失望的是Kotlin中的非数据类需要所有的标准样板.

所以我创建了Kassava,一个开源库,可以让你实现toString()并且equals()没有任何样板 - 只需提供属性列表就可以了!

例如:

// 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)
}
Run Code Online (Sandbox Code Playgroud)


小智 8

我发现Apache Commons Lang的ToStringBuilder反射很有用,但是hashCode()当我不需要它时调用它和其他方法(并且hashCode()从第三方lib 调用的一个生成NPE).

所以我跟着:

// class myClass
    override fun toString() = MiscUtils.reflectionToString(this)

// class MiscUTils
fun reflectionToString(obj: Any): String {
    val s = LinkedList<String>()
    var clazz: Class<in Any>? = obj.javaClass
    while (clazz != null) {
        for (prop in clazz.declaredFields.filterNot { Modifier.isStatic(it.modifiers) }) {
            prop.isAccessible = true
            s += "${prop.name}=" + prop.get(obj)?.toString()?.trim()
        }
        clazz = clazz.superclass
    }
    return "${obj.javaClass.simpleName}=[${s.joinToString(", ")}]"
}
Run Code Online (Sandbox Code Playgroud)