0

我有两个类文件,我试图证明它们是从同一个 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 注释?

谢谢。

4

1 回答 1

2

两个 scala 源文件可能以相同的字节码结束(sig 除外)。事实上,正是信号告诉您原始源文件不同。所以不,不可能证明两个类文件来自同一个 scala 源。

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

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

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

这两种方法生成的字节码完全相同,但信号会不同:

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;
于 2012-10-19T18:57:57.240 回答