Метод в сопутствующем объекте, скомпилированный в статические методы в Scala? - PullRequest
6 голосов
/ 28 октября 2011

Похоже, что scala компилирует методы в сопутствующих объектах в статические методы, что немного упрощает их вызов из кода Java.Например, вы можете написать CompanionObject.method () вместо CompanionObject $ .MODULE $ .method ().Однако иногда, казалось бы, несущественное изменение кода нарушает это поведение.Я придумал этот пример, чтобы проиллюстрировать проблему

$ cat TestCompanion.scala 
class TestCompanion

object TestCompanion {
  def init2 {}
}

@SerialVersionUID(1L)
class TestCompanion2

object TestCompanion2 {
  def init2 {}
}


$ scalac -version
Scala compiler version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL

$ scalac TestCompanion.scala
$ javap TestCompanion
Compiled from "TestCompanion.scala"
public class TestCompanion extends java.lang.Object implements scala.ScalaObject{
    public static final void init2();
    public TestCompanion();
}

$ javap TestCompanion2
Compiled from "TestCompanion.scala"
public class TestCompanion2 extends java.lang.Object implements scala.ScalaObject{
    public static final long serialVersionUID;
    public static {};
    public TestCompanion2();
}

Так что единственное различие между TestCompanion и TestCompanion2 заключается в том, что последний аннотируется @SerialVersionUID, а init2 компилируется в статический метод в TestCompanion, но неTestCompanion2.

Может кто-нибудь объяснить, почему scalac по-разному относится к этим двум классам?Я не понимаю, как аннотация @SerialVersionUID должна влиять на доступность статических методов.

1 Ответ

4 голосов
/ 28 октября 2011

Это известная ошибка: Статические серверы пересылки отсутствуют после добавления @ SerialVersionUID , созданного Джошем Коф. Из описания ошибки:

В следующем коде добавление @SerialVersionUID к результатам класса в статических серверах пересылки, отсутствующих в байт-коде.

object WithoutUID {
 val instance = new WithoutUID
}
class WithoutUID extends scala.Serializable

object WithUID {
 val instance = new WithUID
}
@SerialVersionUID(0) 
class WithUID extends scala.Serializable

Вот соответствующий декомпилированный байт-код:

public class WithoutUID implements Serializable, ScalaObject {
  public static final WithoutUID instance(){
    return WithoutUID.MODULE$.instance();
  }
}

public class WithUID implements Serializable, ScalaObject {
  public static final long serialVersionUID = 0L;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...