通过反射获取特定的公共字段(适用于所有父类)

时间:2016-03-25 12:38:01

标签: scala reflection

如何从某个对象实例中获取具有特定类型的所有字段,包括其所有父类?

例如,有以下类:

trait Target {
    val message: String
    def action: Unit = println("hello", message)
}

class ConcreteTarget(val message: String) extends Target

trait BaseSet {
  val s = ""
  val t1 = new ConcreteTarget("A")
  val t2 = new ConcreteTarget("B")
  val a = 123
}

class ExtendedSet extends BaseSet {
  val t3 = new ConcreteTarget("C")
  val f = "111"
}

我已尝试使用write方法获取所有Target字段:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}

def find(instance: Any): List[Target] = {
    val m = ru.runtimeMirror(instance.getClass.getClassLoader)
    val i = m.reflect(instance)

    i.symbol.typeSignature.decls.flatMap {
      case f: TermSymbol if !f.isMethod => i.reflectField(f).get match {
        case d: Target => Some(d)
        case _ => None
      }
      case _ => None
    }.toList
}

此方法适用于BaseSet

find(new BaseSet{}) foreach (_.action)
//> (hello,A)
//> (hello,B)

但是只查找来自ExtendedSet的公共字段,并且找不到父字段:

find(new ExtendedSet) foreach (_.action)
//> (hello,C)

有什么问题?

1 个答案:

答案 0 :(得分:1)

decls不包含继承成员;您正在寻找members