2016-04-18 29 views
0

我试图使用Scala的反射来实现这一点:我可以使用内部类类型的反射来获得外部类的实例吗?

val labelBar = Named("bar") 
val labelFoo = NamedFunc("foo", (i: Int) => println(i)) 

val i = newInstance[ 
    labelBar.Var[Int] + 
    labelFoo.Func[Int => Unit] 
    ] 

i.foo(2) 
i.bar = 20 

它采用了newInstace方法来创建指定成员的新对象。为了允许动态成员,我使用Scala的Dynamic类。
newInstance采用隐式TypeTag参数。 Var是Named类的内部类:

case class Named(name: String) { 
    outer => 
    class Var[T]() { 
    def getOuter: Named = outer 
    } 
} 

class +[A, B] 

我的问题是我无法在表示内部类的Type上使用reflectClass。它抛出:

scala.ScalaReflectionException: class asVar is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror 
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$abort(JavaMirrors.scala:115) 
at scala.reflect.runtime.JavaMirrors$JavaMirror.ErrorInnerClass(JavaMirrors.scala:117) 
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectClass(JavaMirrors.scala:183) 

有没有办法解决它?斯卡拉甚至持有这个实例吗?

编辑1: newInstance方法不会将labelFoo实例作为参数,所以我无法按照异常消息中的建议。

+0

请注意,您需要从参数_somehow_中获取'labelFoo'和'labelBar',否则您将无法访问所需的名称和函数。一旦你这样做,你可以按照建议。如果您试图通过某种方式“实例化”labelBar.Var而无法访问'labelBar'然后调用'getOuter',我认为这是不可能的。 –

+0

@AlexeyRomanov这正是我想要实现的。如果我理解正确,外部类实例是嵌套类类型的“组件”。我不能这样做: 'val label:labelBar.Var = new labelFoo.Var()' 它可以使用scala类型参数传递值。 – Jaca

+0

值本身不是。即使'labelBar'和'labelFoo'具有相同的值,您也无法完成上述操作。符号(或者更一般地说,一个稳定的路径)是,并且可以通过我的答案中提到的TypeRef来访问。 –

回答

1

有没有办法避开它?

是,错误消息明确表示,它是什么:

上InstanceMirror使用reflectClass获得其ClassMirror

即而不是mirror.reflectClass(classSymbol)请致电mirror.reflect(labelBar).reflectClass(classSymbol)(假设您想为嵌套在labelBar中的类获得ClassMirror)。要找到该实例,可以尝试匹配typeTag.tpeTypeRef

+0

问题是,newInstance方法不会将labelBar作为参数,所以我不能做什么异常说。我可以访问的唯一东西是嵌套类的TypeTag。 – Jaca

+0

“要查找实例,可以尝试将typeTag.tpe与TypeRef进行匹配。” –

相关问题