看起来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注释应该如何影响静态方法的可用性。
答案 0 :(得分:4)
这是一个已知的错误:Static forwarders are missing after adding @SerialVersionUID,由Josh Cough提出。从错误的描述:
在以下代码中,将@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;
}