什么是Scala对象的Java等价物?

在Scala中,我们可以写

object Foo { def bar = {} } 

这是如何由编译器实现的? 我可以调用Foo.bar(); 来自Java但new Foo(); 从Java给出错误cannot find symbol symbol: constructor Foo()

  • JVM本身是否支持单例?
  • 是否有可能在Java中有一个没有构造函数的类?

注意:这是scalac -print输出的代码

 package  { final class Foo extends java.lang.Object with ScalaObject { def bar(): Unit = (); def this(): object Foo = { Foo.super.this(); () } } } 

对单身人士的支持不是语言水平,但语言提供了足够的设施来创建它们而没有任何麻烦。

请考虑以下代码:

 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构造函数,则不必编写它。

编译代码时,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方法。

Joshua Bloch在“Effective Java”一书中推荐使用枚举来实现单例。

看到这个问题: 在Java中实现单例模式的有效方法是什么?