反射:显示静态类型的字节码类型签名

时间:2012-07-25 22:23:03

标签: scala scala-2.10

是否可以使用新的反射库显示保存在字节码中的完整类型签名(使用已擦除的参数化类型)?

例如类型

Any => Unit

应显示为

"scala.Function1<java.lang.Object,scala.runtime.BoxedUnit>"

因为那是存储在字节码中的类型。可以使用javap显示此类型。首先需要使用scalac编译一些代码:

object X {
  def m(f: Any => Unit) = f
}

命令javap -c -s -l -verbose X$显示:

...
const #25 = Asciz   (Lscala/Function1<Ljava/lang/Object;Lscala/runtime/BoxedUnit;>;)Lscala/Function1<Ljava/lang/Object;Lscala/runtime/BoxedUnit;>;;
...
public scala.Function1 m(scala.Function1);
  Signature: (Lscala/Function1;)Lscala/Function1;
...

javap的输出有点奇怪我更感兴趣的是“Java like”输出。也许是一个表示类型签名的字符串,更容易生成这个字符串的类型。

另一个例子:

package abc
object O {
  def x(i: Int)(j: Int) = i+j
}

// type of x should be displayed something like
"int abc.O$.x(int, int)"

这样的东西是否已经被支持,如果没有,如何为任何类型构建这样的输出?

1 个答案:

答案 0 :(得分:0)

类型已经是完整类型签名,但它们不包括完整路径。为此,你必须去符号并得到它的主人,或类似的东西。

关于新反思的每一个问题都是这样做的,所以如果你可以更具体一点,那就会有所帮助。

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[abc.O.type].member(newTermName("x")).typeSignatureIn(typeOf[abc.O.type])
res0: reflect.runtime.universe.Type = (i: scala.Int)(j: scala.Int)scala.Int