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