Scala的多个参数列表如何编码为JVM字节码

时间:2015-08-18 20:01:00

标签: java scala bytecode

在Scala中,以下两个功能不同:

def paren(): Int = 42
def noparen: Int = 42

第一个参数列表中有1个零参数,而下一个参数列表中有0参数列表。

但是,使用javap -v查看时,它们的字节码相同:

public int paren();
  Signature: ()I
  flags: ACC_PUBLIC
  Code:
    stack=1, locals=1, args_size=1
       0: bipush        42
       2: ireturn
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
             0       3     0  this   LParentheses$;
    LineNumberTable:
      line 4: 0

public int noparen();
  Signature: ()I
  flags: ACC_PUBLIC
  Code:
    stack=1, locals=1, args_size=1
       0: bipush        42
       2: ireturn
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
             0       3     0  this   LParentheses$;
    LineNumberTable:
      line 5: 0

Scala编译器在哪里存储参数列表的维度?

2 个答案:

答案 0 :(得分:3)

为了测试这一点,我使用了以下代码,并使用了javap -v

@Deprecated //add an annotation for reference
class Test {
  def test: Unit = ???
  def test2(): Unit = ???
}

在最后,有这样的输出:

SourceFile: "Test.scala"
RuntimeVisibleAnnotations:
  0: #6()
  1: #7(#8=s#9)
Error: unknown attribute
  ScalaSig: length = 0x3
   05 00 00

#6@Deprecated#7(#8=s#9)@scala.reflect.ScalaSignature(bytes=...)。因此,即使有多个方法,并且类也有自己的签名,只有一个ScalaSignature注释以一些二进制格式编码所有其他签名信息。

您已经在SID-10中指向answer,其中声明签名已被压缩(这很明显,因为其中没有可识别的类名),并且{在Scala 2.8之前使用了{1}}类文件属性。 (更改的原因被解释为运行时的反射访问 - (至少未知)属性不由JVM保留;具有适当保留的注释是。)

另外需要注意的是,虽然Scala签名是Java签名的超集,但Java签名仍然必须是唯一的 - 在运行时,JVM并不关心Scala。

PS:这也是用其他JVM语言完成的;在我所知道的情况下,AspectJ绝对是这样。我认为仿制药也可以通过这种方式实现,但它们并非如此;他们在类文件格式中有自己的编码。

答案 1 :(得分:1)

虽然没有明确提及,

SID-10表示这些信息将存储在ScalaSignature中。