2015-08-18 1 views
4

В Scala, следующие две функции отличаются:Как несколько списков параметров в Scala получить закодированы в JVM байткод

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 компилятор магазин размерность списков параметров?

ответ

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, где говорится, что подпись сжимается (что вполне очевидно, учитывая, что нет никаких узнаваемых имен классов в там), и что атрибут файла ScalaSig класса был использован для этого до Scala 2.8. (Причина изменения объясняется как доступность отражения во время выполнения - (по крайней мере неизвестные) атрибуты не сохраняются JVM, аннотации с надлежащим сохранением.)

Еще одна вещь, которую следует отметить, заключается в том, что, хотя подписи Scala являются надмножеством сигнатур Java, сигнатуры Java по-прежнему должны быть уникальными - во время выполнения JVM не заботится о Scala.


PS: это также делается на других языках JVM; один, где я знаю, что это определенно случай AspectJ. Я думаю, что дженерики могли бы быть реализованы таким же образом, но это не так; они имеют собственную кодировку в формате файла класса.

+0

Мартин Одерски разработал и внедрил Generics во время Java 1.0 таймфрейма, на самом деле написанный им Java-компилятор уже был отправлен с 1.2 (и по-прежнему остается в комплекте с Oracle JDK и OpenJDK), как раз с отключенными битами Generics. Аннотации были добавлены только в Java 5. Если раньше существовали аннотации, или Generics были позже разработаны, кто знает, может быть, мы бы уже доработали Generics. –

1

Хотя это явно не говоря уже о его,

SID-10 предполагает, что те, информация будет храниться в ScalaSignature.

Смежные вопросы