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



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

例如类型

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"的输出。也许一个代表类型签名的字符串是一个更好的类型,它可以很容易地生成这个字符串。

另一个例子:

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)"

这样的东西已经得到支持了吗?如果没有,如何为任何类型构建这样的输出?

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

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

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

最新更新