Singletons as Synthetic classes in Scala?

后端 未结 2 1327
说谎
说谎 2020-12-06 00:27

I am reading Programming in Scala, and I don\'t understand the following sentence (pdf p.112):

Each singleton object is implemented as an instance of

相关标签:
2条回答
  • 2020-12-06 01:01

    The chapter 31 of the same "Programming in Scala" is more precise:

    Java has no exact equivalent to a singleton object, but it does have static methods.

    The Scala translation of singleton objects uses a combination of static and instance methods. For every Scala singleton object, the compiler will create a Java class for the object with a dollar sign added to the end.
    For a singleton object named App, the compiler produces a Java class named App$.
    This class has all the methods and fields of the Scala singleton object.
    The Java class also has a single static field named MODULE$ to hold the one instance of the class that is created at run time.
    As a full example, suppose you compile the following singleton object:

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

    Scala will generate a Java App$ class with the following fields and methods:

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

    That’s the translation for the general case.

    0 讨论(0)
  • 2020-12-06 01:12

    You're basically correct.

    If you have the singleton

    object Singleton {
      def method = "Method result"
    }
    

    then compilation gives you

    Singleton.class
    Singleton$.class
    

    and for the bytecode you find, first for 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
    }
    

    that is, a public static method for each method of the class that references something called Singleton$.MODULE$, and in 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
    }
    

    Where you see that MODULE$ is what holds the instance of Singleton$, and method is just an ordinary method.

    So, that's all there really is to it: create Singleton$ with a static field called MODULE$ to hold the unique instance of itself, populate that field, and then create a Singleton with static methods that forward all static calls to the appropriate methods from Singleton$.

    0 讨论(0)
提交回复
热议问题