Scala 2.10反射:类中的case类的构造函数

时间:2013-02-24 17:50:04

标签: scala reflection case-class

我已经使用这个问题的接受答案来构建小帮助类来从值数组构造case类: construct case class from collection of parameters

正如答案中所提到的,内部案例类不起作用。你得到了一个

ScalaReflectionException: class X is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror  

我无法弄清楚如何使用InstanceMirror,因为例外情况解释了。这是我当前的REPL-able代码(由于缓存而略微复杂)。

import scala.reflect.runtime.universe._ 

object ReflectUtil {
  private val constructorCache = collection.mutable.HashMap[String, MethodMirror]()

  def constructFromSeq[T: TypeTag](args: Seq[Any]): T = {
    val tag = typeTag[T]
    val strTag = tag.toString
    var constructorMirror = constructorCache.getOrElseUpdate( strTag, {
      val rm = runtimeMirror(getClass.getClassLoader)
      val classSymbol = tag.tpe.typeSymbol.asClass
      val classMirror = rm.reflectClass(classSymbol) // wrap with try/catch?
      val constructorSymbol = tag.tpe.declaration(nme.CONSTRUCTOR).asMethod
      classMirror.reflectConstructor(constructorSymbol)
    })
    constructorMirror(args: _*).asInstanceOf[T]
  } 
}   

case class X(a:String, b:Int)

class Out { 
  case class Y(a:String, b:Int) 

  def buildY(arr:Array[Any]) = {
    ReflectUtil.constructFromSeq[Y](arr)
  }
}

val arr = Array[Any]("asdf", 1234)
ReflectUtil.constructFromSeq[X](arr) // this works

val inst = new Out
inst.buildY(arr) // this doesn't work

1 个答案:

答案 0 :(得分:4)

什么例外意味着你需要一个外部引用来构造一个内部类的实例(例如,构造Y你需要一个Out的实例。然后你可以做rm.reflect(instanceOfOut).reflectClass...