我正在阅读Scala编程,我不理解以下句子(pdf第112页):
每个单例对象都实现为从静态变量引用的合成类的实例,因此它们具有与Java静态相同的初始化语义.
这是否意味着如果我在scala中有单例FooBar,编译器将创建一个名为FooBar $的类?
另外作者的意思是"从静态变量引用"?是否有一个隐藏的静态变量,某处持有对某些FooBar $类的引用?
我感谢任何帮助.
Von*_*onC 24
同样的"Scala编程"第31章更精确:
Java与单例对象没有完全等价,但它确实有静态方法.
单例对象的Scala转换使用静态和实例方法的组合.对于每个Scala单例对象,编译器将为对象创建一个Java类,并在末尾添加一个美元符号.
对于名为singleton的对象App,编译器会生成一个名为的Java类App$.
此类包含Scala单例对象的所有方法和字段.
Java类还有一个静态字段,MODULE$用于保存在运行时创建的类的一个实例.
作为一个完整的示例,假设您编译以下单例对象:
object App {
def main(args: Array[String]) {
println("Hello, world!")
}
}
Run Code Online (Sandbox Code Playgroud)
Scala将使用以下字段和方法生成Java App $类:
$ javap App$
public final class App$ extends java.lang.Object
implements scala.ScalaObject{
public static final App$ MODULE$;
public static {};
public App$();
public void main(java.lang.String[]);
public int $tag();
}
Run Code Online (Sandbox Code Playgroud)
这是一般情况的翻译.
Rex*_*err 10
你基本上是正确的.
如果你有单身人士
object Singleton {
def method = "Method result"
}
Run Code Online (Sandbox Code Playgroud)
然后编译给你
Singleton.class
Singleton$.class
Run Code Online (Sandbox Code Playgroud)
对于你找到的字节码,首先是Singleton:
public final class Singleton extends java.lang.Object{
public static final java.lang.String method();
Signature: ()Ljava/lang/String;
Code:
0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$;
3: invokevirtual #13; //Method Singleton$.method:()Ljava/lang/String;
6: areturn
}
Run Code Online (Sandbox Code Playgroud)
也就是说,类的每个方法的公共静态方法引用被调用的东西Singleton$.MODULE$,并在Singleton$:
public final class Singleton$ extends java.lang.Object implements scala.ScalaObject{
public static final Singleton$ MODULE$;
Signature: LSingleton$;
public static {};
Signature: ()V
Code:
0: new #9; //class Singleton$
3: invokespecial #12; //Method "<init>":()V
6: return
public java.lang.String method();
Signature: ()Ljava/lang/String;
Code:
0: ldc #16; //String Method result
2: areturn
private Singleton$();
Signature: ()V
Code:
0: aload_0
1: invokespecial #20; //Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #22; //Field MODULE$:LSingleton$;
8: return
}
Run Code Online (Sandbox Code Playgroud)
你看到的MODULE$是那个实例的东西Singleton$,而且method只是一个普通的方法.
所以,这就是它的全部内容:创建Singleton$一个静态字段,调用它MODULE$来保存自身的唯一实例,填充该字段,然后创建一个Singleton静态方法,将所有静态调用转发给相应的方法Singleton$.