Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singletons as Synthetic classes in Scala?

Tags:

scala

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 a synthetic class referenced from a static variable, so they have the same initialization semantics as Java statics.

Does this mean the if I have a singleton FooBar in scala, the compiler will create a class named FooBar$?

Also what does the author mean by "referenced from a static variable"? Is there a hidden static variable somewhere holding a reference to some FooBar$ class?

I appreciate any help here.

like image 756
Andriy Drozdyuk Avatar asked Apr 19 '11 18:04

Andriy Drozdyuk


People also ask

Are Scala objects singletons?

Instead of static keyword Scala has singleton object. A Singleton object is an object which defines a single object of a class. A singleton object provides an entry point to your program execution. If you do not create a singleton object in your program, then your code compile successfully but does not give output.

What is companion object in Scala?

A companion object in Scala is an object that's declared in the same file as a class , and has the same name as the class. For instance, when the following code is saved in a file named Pizza.scala, the Pizza object is considered to be a companion object to the Pizza class: class Pizza { } object Pizza { }

What is the difference between class and object in Scala?

Difference Between Scala Classes and Objects Definition: A class is defined with the class keyword while an object is defined using the object keyword. Also, whereas a class can take parameters, an object can't take any parameter. Instantiation: To instantiate a regular class, we use the new keyword.

How do you define an object in Scala?

In Scala, an object of a class is created using the new keyword. The syntax of creating object in Scala is: Syntax: var obj = new Dog();


2 Answers

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.

like image 113
VonC Avatar answered Oct 19 '22 20:10

VonC


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$.

like image 43
Rex Kerr Avatar answered Oct 19 '22 21:10

Rex Kerr