我正在尝试使用Scala反射来定义traits和case classes及其伴生对象,以便实现“可导出性”(例如到Map [String,Any])并从中进行“可导入性”。对于顶层case class,它运行得很好,但我无法使内部类起作用。如果我已经有了一个关于封闭实例的处理,我就知道如何通过反射来实例化内部类,这个处理可以反映到InstanceMirror上,但现在我正在编写一个稍后由顶级或内部类实现的trait。
只要伴生对象和构造实例共享相同的封闭实例,我应该能够使其工作。但是我一直没有弄清楚如何通过反射来确定伴生对象的封闭实例。
以下是我正在尝试做的事情的简化示例以及出现的问题:
import scala.reflect.runtime.universe._;
trait CompanionOfReflectiveConstructable[T] {
def tType : Type;
lazy val mirror : Mirror = runtimeMirror( this.getClass.getClassLoader );
lazy val ctorDecl : Symbol = tType.declaration(nme.CONSTRUCTOR);
lazy val ctor : MethodSymbol = ctorDecl.asMethod;
lazy val tClass : ClassSymbol = tType.typeSymbol.asClass;
lazy val tClassMirror : ClassMirror = mirror.reflectClass( tClass );
lazy val ctorF : MethodMirror = tClassMirror.reflectConstructor( ctor );
// in real-life, i'd derive arguments from ctor.paramss
// but to highlight our issue, we'll assume a no arg constructor
def createInstance : T = ctorF().asInstanceOf[T];
}
trait ReflectiveConstructable;
object Test1 extends CompanionOfReflectiveConstructable[Test1] {
def tType = typeOf[Test1];
}
class Test1 extends ReflectiveConstructable;
class Outer {
object Test2 extends CompanionOfReflectiveConstructable[Test2] {
def tType = typeOf[Test2];
}
class Test2 extends ReflectiveConstructable;
}
这是发生的情况。
scala> Test1.createInstance
res0: Test1 = Test1@2b52833d
scala> (new Outer).Test2.createInstance
scala.ScalaReflectionException: class Test2 is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror
at scala.reflect.runtime.JavaMirrors$JavaMirror.ErrorInnerClass(JavaMirrors.scala:126)
...
Test1的表现很好。 Test2的问题很明显 - 我需要通过InstanceMirror而不是通过顶级mirror获取我的ClassMirror。(请参见这里,这里和这里)。但是,在CompanionOfReflectiveConstructable中,我不知道如何检查自己是否为内部对象或者我的封闭实例是谁,以有条件地执行适当的工作。有人知道如何做到这一点吗?
非常感谢!