【问题标题】:Reflection: Show bytecode type signature of static types反射:显示静态类型的字节码类型签名
【发布时间】:2012-07-25 22:23:03
【问题描述】:

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

例如类型

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 scala-2.10


    【解决方案1】:

    类型已经是完整的类型签名,但它们不包括完整的路径。为此,您必须前往符号并获取其所有者,或类似的东西。

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

    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
    

    【讨论】:

    • 我对类型签名的字符串表示感兴趣,因为它保存在字节码中。例如,在您的代码示例中,多个参数列表应仅显示为一个参数列表,因为 JVM 字节码中不存在多个参数列表。
    • @sschaef 那么你的问题没有意义。字节码签名被删除,所以Any =&gt; Unit 只是Function1
    • 签名未被删除(未完全删除)。 javap 为Any =&gt; Unit 显示签名Lscala/Function1&lt;Ljava/lang/Object;Lscala/runtime/BoxedUnit;&gt;
    • @sschaef 在哪里?您是否创建了一个仅包含 Any =&gt; Unit 的文件,编译然后 javap 显示?疑。你没有提供足够的信息,在你提供之前你不会得到有用的答案。不要吝啬细节。
    • 好的,我稍微更新了我的问题。希望现在更清楚了。
    猜你喜欢
    • 2010-11-22
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多