Reputation: 200
case class Keyword(id: Int = 0, words: String)
val my= Keyword(123, "hello")
val fields: Array[Field] = my.getClass.getDeclaredFields
for (i <- fields.indices) {
println(fields(i).getName +":"+ my.productElement(i))
}
id:123
title:keyword's title
it's ok.
def outputCaseClass[A](obj:A){
val fields: Array[Field] = obj.getClass.getDeclaredFields
for (i <- fields.indices) {
println(fields(i).getName +":"+ obj.productElement(i))
}
}
outputCaseClass(my)
it's wrong
Upvotes: 0
Views: 2155
Reputation: 13985
import scala.reflect.runtime.{universe => ru}
def printCaseClassParams[C: scala.reflect.ClassTag](instance: C):Unit = {
val runtimeMirror = ru.runtimeMirror(instance.getClass.getClassLoader)
val instanceMirror = runtimeMirror.reflect(instance)
val tpe = instanceMirror.symbol.toType
tpe.members
.filter(member => member.asTerm.isCaseAccessor && member.asTerm.isMethod)
.map(member => {
val term = member.asTerm
val termName = term.name.toString
val termValue = instanceMirror.reflectField(term).get
termName + ":" + termValue
})
.toList
.reverse
.foreach(s => println(s))
}
// Now you can use it with any case classes,
case class Keyword(id: Int = 0, words: String)
val my = Keyword(123, "hello")
printCaseClassParams(my)
// id:123
// words:hello
Upvotes: 3
Reputation: 1414
productElement is a Method of the Product
Base trait.
Try to use a method signature like this:
def outputCaseClass[A <: Product](obj:A){ .. }
However it still won't work for inner case classes (fields
also reports the $outer
-Field, which productElement won't return and so it crashes with IndexOutOfBoundsException
).
Upvotes: 2