2016-11-29 82 views
11

的toString()我有lateinit领域的一类,所以他们不存在构造函数:科特林 - 生成非数据类

class ConfirmRequest() { 
    lateinit var playerId: String 
} 

我想有toString()方法的所有字段,并且不想手动写入以避免锅炉打印。如果我使用Java,我会使用Lombok @ToString注释解决此问题。有什么方法可以在Kotlin中实现它?

+1

龙目岛可能仍然有效,不是吗? – voddan

+0

Lombok注释不起作用,解释:http://stackoverflow.com/questions/35517325/kotlin-doesnt-see-java-lombok-accessors – awfun

+1

我建议挑战'lateinint var'和“data” 'toString()'在同一个类中。如果不了解更多'ConfirmRequest'的使用方法,很难提出建议,但'数据类ConfirmRequest(var playerId:String?= null)'似乎对我很好。如果你知道'playerId == null'永远不会被使用,那么你可以使数据成员变成私有的,并为了方便公开一个公共的非空属性。 – mfulton26

回答

4

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

data class的目的是为了适应85%的最常见的情况,其中15%是其他解决方案。

+0

好的,必须用IDE生成它 – awfun

+2

最后决定使用允许使用参数构造函数的'jackson-module-kotlin',所以数据类现在适合我的需要: 'data class ConfirmRequest(var playerId:String) – awfun

3

和你一样,我习惯于在Java中使用lombok为toString()equals(),所以有点失望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) 
} 
+0

伟大的技巧,在龙目岛的Java,希望我会知道早些时候:( – ycomp

1

我找到的Apache Commons Lang中的ToStringBuilder与反思是有用的,但是当我不需要说(和一个来自第三方的lib称为hashCode()产生它调用hashCode()等方法一个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(", ")}]" 
}