Scala在运行时获取构造函数参数

Scala在运行时获取构造函数参数,scala,reflection,Scala,Reflection,我试图使用反射在运行时获取类的构造函数参数类型。下面的方法位于抽象超类中。但是,此.type的行为不符合预期。任何帮助都将不胜感激 /** * Maps constructor field names to types * * @return Map[String, Type] */ def getParamTypes: Map[String, ru.Type] = ru.typeOf[this.type]. member(ru.termNam

我试图使用反射在运行时获取类的构造函数参数类型。下面的方法位于抽象超类中。但是,
此.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)
      })

方法
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)
或者,您可以从
获取
类型

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)

方法
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)
或者,您可以从
获取
类型

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)