2016-11-29 79 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(", ")}]" 
}