单例作为Scala中的合成类?
我正在读Scala编程,我不理解下面的句子(pdf第112页): 每个单例对象都实现为从 静态变量,因此它们与Java静态具有相同的初始化语义 这是否意味着如果在scala中有一个单例FooBar,编译器将创建一个名为FooBar$的类 作者所说的“从静态变量引用”是什么意思?是否有一个隐藏的静态变量存放着对某个FooBar$类的引用单例作为Scala中的合成类?,scala,Scala,我正在读Scala编程,我不理解下面的句子(pdf第112页): 每个单例对象都实现为从 静态变量,因此它们与Java静态具有相同的初始化语义 这是否意味着如果在scala中有一个单例FooBar,编译器将创建一个名为FooBar$的类 作者所说的“从静态变量引用”是什么意思?是否有一个隐藏的静态变量存放着对某个FooBar$类的引用 非常感谢您的帮助。您基本上是对的 如果你有单身汉 object Singleton { def method = "Method result" } 那么编
非常感谢您的帮助。您基本上是对的 如果你有单身汉
object Singleton {
def method = "Method result"
}
那么编译给你
Singleton.class
Singleton$.class
对于您找到的字节码,首先对于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
}
也就是说,类中引用名为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
}
public final类Singleton$extends java.lang.Object实现scala.ScalaObject{
公共静态最终单例$MODULE$;
签署:伦敦元;
公共静态{};
签字:()五
代码:
0:new#9;//单例类$
3:invokespecial#12;//方法“”:()V
6:返回
public java.lang.String方法();
签名:()Ljava/lang/String;
代码:
0:ldc#16;//字符串方法结果
2:轮到你了
私人单身人士$();
签字:()五
代码:
0:aload_0
1:invokespecial#20;//方法java/lang/Object。”“:()V
4:aload_0
5:putstatic#22;//字段模块$:LSingleton$;
8:返回
}
您可以看到,MODULE$
保存了Singleton$
的实例,而method
只是一个普通的方法
所以,这就是它真正的意义所在:使用名为
MODULE$
的静态字段创建Singleton$
,以保存其自身的唯一实例,填充该字段,然后使用静态方法创建一个Singleton
,该静态方法将所有静态调用转发到Singleton$
的相应方法。同样的“Scala编程”的第31章更为精确:
Java没有完全等同于单例对象,但它有静态方法
单例对象的Scala转换使用静态方法和实例方法的组合对于每个Scala singleton对象,编译器将为该对象创建一个Java类,并在末尾添加一个美元符号对于名为
App
的单例对象,编译器生成名为App$
的Java类此类包含Scala singleton对象的所有方法和字段。
Java类还有一个名为
模块$
的静态字段来保存该字段
在运行时创建的类的实例。作为完整示例,假设您编译以下单例对象: Scala将生成包含以下字段和方法的Java App$类: 这是一般情况的翻译
是的,我想你理解它了。:-(我不知道,我只是猜了一下!诀窍是静态变量引用实例,而不是类。换句话说,Scala对象
FooBar
在Java中是作为FooBar$.MODULE$
引用的。谢谢你这么说。我想我应该在书中向前跳过:-)publicstatic{}的目的是什么
?@Christopherry静态{}
是一个静态初始化块,用于初始化单例。例如,你看,或者谢谢,这有点清楚,但是数字0 1 4等等是什么?对不起,我不太熟悉字节码lol:(在左边,它们是字节码地址。基本上是行号。在右边,它们指的是类、方法、字段或其他合适的表。
object App {
def main(args: Array[String]) {
println("Hello, world!")
}
}
$ 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();
}