在Scala中,我们可以写
object Foo { def bar = {} }
编译器如何实现?我可以从Java调用Foo.bar();
但是来自Java的new Foo();
会出现错误cannot find symbol symbol: constructor Foo()
注意:这是scalac -print
package <empty> {
final class Foo extends java.lang.Object with ScalaObject {
def bar(): Unit = ();
def this(): object Foo = {
Foo.super.this();
()
}
}
}
答案 0 :(得分:22)
编译代码时,Scala编译器会生成以下Java代码的等效代码:
public final class Foo {
private Foo() {} // Actually, Foo doesn't have constructor at all
// It can be represented in bytecode,
// but it cannot be represented in Java language
public static final void bar() {
Foo$.MODULE$.bar();
}
}
public final class Foo$ implements ScalaObject {
public static final Foo$ MODULE$;
static {
new Foo$();
}
private Foo$() { MODULE$ = this; }
public final void bar() {
// actual implementation of bar()
}
}
此处Foo$
是单例的实际实现,而Foo
提供了与Java交互的static
方法。
答案 1 :(得分:11)
对单身人士的支持不在语言层面,但该语言提供了足够的设施来创建它们。
请考虑以下代码:
public class Singleton {
private static final Singleton instance = new Singleton();
// Private constructor prevents instantiation from other classes
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
这是来自维基百科的一个例子,它解释了如何制作单身人士。实例保存在私有字段中,构造函数在类外部不可访问,该方法返回此单个实例。
至于构造函数:默认情况下,每个类都有一个所谓的默认构造函数,它不带参数,只调用超类的no-args构造函数。如果超类没有任何没有参数的可访问构造函数,则必须编写显式构造函数。
所以类必须有一个构造函数,但如果超类有一个no-args构造函数,则不必编写它。
答案 2 :(得分:4)
Joshua Bloch在“Effective Java”一书中建议使用枚举来实现单例。
看到这个问题: What is an efficient way to implement a singleton pattern in Java?