In Scala, we can write
object Foo { def bar = {} }
How is this implemented by the compiler? I am able to call Foo.bar();
from Java
but new Foo();
from Java gives the error cannot find symbol symbol: constructor Foo()
- Does the JVM support singletons natively?
- Is it possible to have a class in Java that does not have a constructor?
Note: here is the code output by scalac -print
package <empty> {
final class Foo extends java.lang.Object with ScalaObject {
def bar(): Unit = ();
def this(): object Foo = {
Foo.super.this();
()
}
}
}
Support for singletons is not on a language level, but the language provides enough facilities to create them without any trouble.
Consider the following code:
This is an example from Wikipedia, which explains how a singleton can be made. An instance is kept in a private field, constructor is inaccessible outside the class, the method returns this single instance.
As for constructors: every class by default has a so-called default constructor which takes no arguments and simply calls the no-args constructor of the superclass. If the superclass doesn't have any accessible constructor without arguments, you will have to write an explicit constructor.
So a class must have a constructor, but you don't have to write it if the superclass has a no-args constructor.
When compiling your code, Scala compiler produces an equivalent of the following Java code:
Here
Foo$
is an actual implementation of a singleton, whereasFoo
provides astatic
method for interaction with Java.Joshua Bloch recommened in the book "Effective Java" the use of an enum to implement a singleton.
See this question: What is an efficient way to implement a singleton pattern in Java?