单身人士作为Scala的综合课程?

And*_*yuk 17 scala

我正在阅读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$.