微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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编译器在哪里存储参数列表的维度?

解决方法:

为了测试这个,我使用了以下代码,并使用了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注释以一些二进制格式编码所有其他签名信息.

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

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

PS:这也是用其他JVM语言完成的;一个我知道的情况肯定是AspectJ.我认为仿制药也可以用这种方式实现,但它们不是;他们在类文件格式中有自己的编码.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐