Scala 反射:getDeclaringTrait? [英] scala reflection: getDeclaringTrait?

查看:34
本文介绍了Scala 反射:getDeclaringTrait?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我研究一个新的库时,我有时会发现很难找到一个方法的实现.

When I research a new library, I sometimes find it hard to locate the implementation of a method.

在 Java 中,Metho#getDeclaringClass 提供声明给定方法的类.因此,通过迭代 Class#getMethods,我可以为每个方法找到声明它的类.

In Java, Metho#getDeclaringClass provides the class that declared a given method. So by iterating over Class#getMethods, I can find for each method, the class that declared it.

在 Scala 中,trait 被转换为 Java 接口,扩展 trait 的类将通过将它们转发到静态定义这些方法的伴随类来实现 trait 的方法.这意味着 Method#getDeclaringClass 将返回类,而不是特征:

In Scala, traits are converted to Java interfaces and a class that extends a trait will implement the methods of the trait by forwarding them to a companion class defining these methods statically. This means, that Method#getDeclaringClass will return the class, not the trait:

scala> trait A { def foo = {println("hi")}}
defined trait A

scala> class B extends A
defined class B

scala> classOf[B].getMethods.find(_.getName() == "foo").get.getDeclaringClass
res3: java.lang.Class[_] = class B

解决此问题的最佳方法是什么?意思是,给定一个类,我怎样才能得到一个 List[(Method, Class)] ,其中每个元组都是一个方法以及它在其中声明的特征/类?

What is the best way to work around this? Meaning, given a class, how can I get a List[(Method, Class)] where each tuple is a method and the trait/class it was declared in?

推荐答案

在 Scala 2.8 中,您可以使用 ScalaSigParser 来解析 Scala 特定的字节码信息.

In Scala 2.8 you can use the ScalaSigParser to parse the scala specific byte code information.

这会比scala trait、类和方法的字节码序列化格式更稳定.

This will be more stable than the byte code serialization format of scala traits, classes and methods.

import tools.scalap.scalax.rules.scalasig._
import scala.runtime._

val scalaSig = ScalaSigParser.parse(classOf[RichDouble]).get
val richDoubleSymbol = scalaSig.topLevelClasses.head
val methods = richDoubleSymbol.children filter ( _ match {
    case m : MethodSymbol => true
    case _ => false
})

methods foreach println
richDoubleSymbol.isTrait
ScalaSigParser.parse(classOf[Ordered[Any]]).get.topLevelClasses.head.isTrait

打印:

scala> methods foreach println
MethodSymbol(x, owner=0, flags=20080004, info=23 ,None)
MethodSymbol(<init>, owner=0, flags=200, info=33 ,None)
[...]
MethodSymbol(isPosInfinity, owner=0, flags=200, info=117 ,None)
MethodSymbol(isNegInfinity, owner=0, flags=200, info=117 ,None)

scala> richDoubleSymbol.isTrait
res1: Boolean = false

scala> ScalaSigParser.parse(classOf[Ordered[Any]]).get.topLevelClasses.head.isTrait
res2: Boolean = true

我想沿着这条路你可以为 Scala 构建一个反射 API.

I suppose following this road you can build a reflection API for Scala.

这篇关于Scala 反射:getDeclaringTrait?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆