我正在尝试使用反射来获取运行时类的构造函数参数的类型。下面的方法是在抽象超类中。但是this.type
的行为不符合预期。任何帮助将不胜感激。
/**
* Maps constructor field names to types
*
* @return Map[String, Type]
*/
def getParamTypes: Map[String, ru.Type] =
ru.typeOf[this.type].
member(ru.termNames.CONSTRUCTOR)
.asMethod.paramLists(0).
foldRight(Map(): Map[String, ru.Type])((p, a) => {
a + (p.name.decodedName.toString -> p.typeSignature)
})
答案 0 :(得分:3)
方法typeOf
需要隐式TypeTag
。您应该直接使用TypeTag
来获取仅在呼叫方可用的类型信息:
trait Test {
def getParamTypes(implicit ttag: ru.TypeTag[this.type]) =
ttag.tpe.
member(ru.termNames.CONSTRUCTOR).
asMethod.paramLists(0).
foldRight(Map(): Map[String, ru.Type])((p, a) => {
a + (p.name.decodedName.toString -> p.typeSignature)
})
}
class TestC(i: Int, s: String) extends Test
val t = new TestC(1, "")
t.getParamTypes
// Map[String,Type] = Map(s -> String, i -> Int)
或者,您可以从Type
获得this
Class
。
trait Test2 {
def getParamTypes: Map[String, ru.Type] = {
val clazz = getClass
val tpe = ru.runtimeMirror(clazz.getClassLoader).classSymbol(clazz).toType
tpe.
member(ru.termNames.CONSTRUCTOR).
asMethod.paramLists(0).
foldRight(Map(): Map[String, ru.Type])((p, a) => {
a + (p.name.decodedName.toString -> p.typeSignature)
})
}
}
class TestC2(i: Int, s: String) extends Test2
new TestC2(1, "").getParamTypes
// Map[String,Type] = Map(s -> String, i -> Int)