scala - 如何在运行时确定 Scala 类的属性?

标签 scala reflection runtime introspection

我想在运行时以编程方式确定 Scala 类的所有属性。例如,对于以下 Scala 类,我想确定方法 name1 , name3 , name4 , 和 name5A 属性的 setter/getter :

class A(val name1: String, private val name2: String) {
  val name3 = ""
  var name4 = ""
  def name5 = ""
  def name6() = ""
}

大多数工作都可以使用 Java 的反射 API 来完成。不幸的是,我无法检测到 name5 之间的区别。和 name6() .因此,我开始使用 ScalaSigParser 进行下一次试验,但 ScalaSig 的标志为 name5name6()不幸的是也一样。这是我的代码:
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)
}

正如您在以下输出中所看到的,这两种方法的区别仅在于 info值(value):
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)

然而,info似乎没有返回静态常量。如果您向类中添加另一个方法 info name6 的值会改变,而似乎有一些稳定性:
  • name3 , name4 , 和 name5一直都一样info
  • name6name5总是与众不同info

  • 有人知道info的意思吗?以及如何使用它来确定它是哪种方法?

    相关问题:
  • How does Scala know the difference between “def foo” and “def foo()”?
  • 最佳答案

    最好的办法是使用即将发布的 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)
    

    不幸的是,关于它的阅读 Material 还很少。虽然有一些关于 SO 的回答问题。例如,this您可能感兴趣的问题。也请查看 this Daniel Sobral 的博文。

    关于scala - 如何在运行时确定 Scala 类的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11934088/

    相关文章:

    scala - 为什么2.11.1失败并显示错误:找不到:键入Application?

    c# - 使用反射从 Soap Client 获取 Web 服务方法

    java - getDeclaredMethods() + 创建数组 = 额外方法?

    python - 按索引删除列表元素是否比按值删除更有效?

    Scala : creating directory and file

    scala - 为 A 和 B 类型创建 given 的最简单方法是什么?

    java - 当系统上安装多个 JRE 时,使用哪个 rt.jar?

    c++ - 类可以在运行时在 C++ 中添加友元类吗?

    scala - 如何覆盖 Scala 中的预定义函数?

    c# - ILGenerated 方法中的 System.ObjectDisposedException