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

Jus*_*s12 12 java scala scala-java-interop

在Scala中,我们可以写

object Foo { def bar = {} }
Run Code Online (Sandbox Code Playgroud)

这是如何由编译器实现的?我能够Foo.bar();从Java 调用,但是new Foo();从Java中调用错误cannot find symbol symbol: constructor Foo()

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

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

package <empty> {
  final class Foo extends java.lang.Object with ScalaObject {
    def bar(): Unit = ();
    def this(): object Foo = {
      Foo.super.this();
      ()
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

Foo$是单例的实际实现,而Foo提供了static与Java交互的方法.

  • @Jus12:也许一些反编译器能够显示它,但我从`javap -c -private Foo` / `javap -c -private Foo$` 的输出手动重建它 (2认同)

Mal*_*olm 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是维基百科的一个例子,它解释了如何制作单身人士.实例保存在私有字段中,构造函数在类外部不可访问,该方法返回此单个实例.

至于构造函数:默认情况下,每个类都有一个所谓的默认构造函数,它不带参数,只调用超类的no-args构造函数.如果超类没有任何没有参数的可访问构造函数,则必须编写显式构造函数.

所以一个类必须有一个构造函数,但如果超类有一个no-args构造函数,你就不必编写它.