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

时间:2011-04-19 18:38:21

标签: scala

我正在阅读Scala编程,我不理解以下句子(pdf第112页):

  

每个单例对象都是作为从a引用的合成类的实例实现的   静态变量,因此它们具有与Java静态相同的初始化语义。

这是否意味着如果我在scala中有单个 FooBar ,编译器将创建一个名为 FooBar $ 的类?

作者的意思是“从静态变量引用”是什么意思?是否存在隐藏的静态变量,其中包含对某些 FooBar $ 类的引用?

我感谢你们的任何帮助。

2 个答案:

答案 0 :(得分:24)

相同的“Scala编程”第31章更精确:

  

Java与单例对象没有完全等价,但它确实有静态方法。

     

单例对象的Scala转换使用静态和实例方法的组合。 对于每个Scala单例对象,编译器将为对象创建一个Java类,并在末尾添加美元符号
  对于名为App的单个对象,编译器会生成一个名为App$的Java类   该类包含Scala单例对象的所有方法和字段   Java类还有一个名为 MODULE$ 的静态字段来保存一个   在运行时创建的类的实例   作为一个完整的示例,假设您编译以下单例对象:

object App {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}
  

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();
}
  

这是一般情况的翻译。

答案 1 :(得分:10)

你基本上是对的。

如果你有单身人士

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
}

您看到MODULE$Singleton$的实例,而method只是一种普通方法。

所以,这就是它的全部内容:使用名为Singleton$的静态字段创建MODULE$以保存其自身的唯一实例,填充该字段,然后创建Singleton使用静态方法将所有静态调用转发到Singleton$的适当方法。