是否可以将相同的Scala源文件编译为包含不同@ScalaSignature注释的类文件?

时间:2012-10-19 18:10:26

标签: scala

我有两个类文件,我试图证明是从同一个Scala源生成的。

在将类文件反编译为Java后,我得到了两个语义完全相同的Java文件。但是,它们内部有不同的@ScalaSignature注释。在类文件上运行“javap -verbose”时,我得到了以下输出:

...
SourceFile: "ABC.scala"
ScalaSig: length = 0x3
 05 00 00
Signature: #140                         // <T:Ljava/lang/Object;>Lcom/xyz/ABC;Lscala/ScalaObject;Lscala/Product;
Lscala/Serializable;
RuntimeVisibleAnnotations:
  0: #141(#142=s#143)
minor version: 0
major version: 49
flags: ACC_PUBLIC, ACC_SUPER
---

来自一个文件,另一个来自:

...
SourceFile: "ABC.scala"
ScalaSig: length = 0x3
 05 00 00
Signature: #140                         // <T:Ljava/lang/Object;>Lcom/xyz/ABC;Lscala/ScalaObject;Lscala/Product;
Lscala/Serializable;
RuntimeVisibleAnnotations:
  0: #141(#142=s#143)
minor version: 0
major version: 49
flags: ACC_PUBLIC, ACC_SUPER
...

是否可以从相同的Scala源获取两个类文件,使用相同的ScalaSig,Signature等进行注释,但是具有不同的@ScalaSignature注释?

感谢。

1 个答案:

答案 0 :(得分:2)

两个scala源文件最终可能使用相同的字节代码(sig除外)。实际上,它是告诉你原始源文件不同的信号。所以不,不可能证明两个类文件来自同一个scala源。

例如,如果两个类具有相同的方法但具有不同的类型参数,那么您将得到相同的字节码,但不同的sigs。

作为一个简单的例子,请看下面的类:

class Foo {
  def fn1(t: String) = "" + t
  def fn2[T <: String](t : T) = "" + t
}

这两种方法生成的字节代码完全相同,但sigs会有所不同:

public java.lang.String fn1(java.lang.String);
  Code:
   Stack=1, Locals=2, Args_size=2
   0:   aload_1
   1:   invokestatic    #12; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   4:   areturn
  LineNumberTable:
   line 2: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      5      0    this       LFoo;
   0      5      1    t       Ljava/lang/String;

  Signature: length = 0x2
   00 12

public java.lang.String fn2(java.lang.String);
  Code:
   Stack=1, Locals=2, Args_size=2
   0:   aload_1
   1:   invokestatic    #12; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   4:   areturn
  LineNumberTable:
   line 3: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      5      0    this       LFoo;
   0      5      1    t       Ljava/lang/String;