Ste*_*lis 3 reflection scala runtime introspection
我想以编程方式在运行时确定Scala类的所有属性.例如,对于下面的Scala类,我想确定方法name1
,name3
,name4
,和name5
是为干将的性质A
:
class A(val name1: String, private val name2: String) {
val name3 = ""
var name4 = ""
def name5 = ""
def name6() = ""
}
Run Code Online (Sandbox Code Playgroud)
大多数工作都可以使用Java的反射API完成.遗憾的是我没能检测之间的差异name5
和name6()
.因此,我开始使用ScalaSigParser下一个试验,但ScalaSig的标志对name5
和name6()
是不幸的也是相同的.这是我的代码:
def gettersOf(clazz: Class[_]) = {
for (ssig <- ScalaSigParser.parse(clazz))
yield {
ssig.symbols.toList.collect{
case m: MethodSymbol => m
}.filter(m => (m.symbolInfo.flags & 0xFFFFF) == 0x200)
}
}
gettersOf(classOf[A]).get.foreach{m =>
println(m.name + ": " + m)
}
Run Code Online (Sandbox Code Playgroud)
正如您在以下输出中看到的,两种方法仅在info
值上有所不同:
name1: MethodSymbol(name1, owner=0, flags=28400200, info=22 ,None)
<init>: MethodSymbol(<init>, owner=0, flags=200, info=38 ,None)
name3: MethodSymbol(name3, owner=0, flags=8400200, info=45 ,None)
name4: MethodSymbol(name4, owner=0, flags=8000200, info=45 ,None)
name4_$eq: MethodSymbol(name4_$eq, owner=0, flags=8000200, info=54 ,None)
name5: MethodSymbol(name5, owner=0, flags=200, info=45 ,None)
name6: MethodSymbol(name6, owner=0, flags=200, info=66 ,None)
Run Code Online (Sandbox Code Playgroud)
但是,info
似乎没有返回静态常量.如果你在类中添加另一个方法,那么info
值name6
会发生变化,而且似乎有一些稳定性:
name3
,name4
并且name5
始终具有相同的info
价值name6
并且name5
总是有不同的info
价值观有人知道它的含义info
以及如何使用它来确定它是哪种方法?
相关问题:
最好的办法是使用即将推出的Scala 2.10的反射API.
以下是如何在2.10.0-M6中获取类型的属性:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> typeOf[A].members.view.filter{_.isValue}.filter{!_.isMethod}.toList
res0: List[reflect.runtime.universe.Symbol] = List(variable name4, value name3, value name2, value name1)
Run Code Online (Sandbox Code Playgroud)
不幸的是,它的阅读材料还不多.尽管如此,有一些已回答的问题.例如,您可能会对此问题感兴趣.另请查看Daniel Sobral撰写的这篇博文.