13

Scala では、次のように記述できます。

object Foo { def bar = {} }

これはコンパイラによってどのように実装されていますか? Javaから呼び出すことはできFoo.bar();ますが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();
      ()
    }
  }
}
4

3 に答える 3

23

コードをコンパイルすると、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$これはシングルトンの実際の実装ですが、Java とのやり取りFooの方法を提供します。static

于 2011-10-19T10:44:19.247 に答える
12

シングルトンのサポートは言語レベルではありませんが、言語はシングルトンを問題なく作成するのに十分な機能を提供します。

次のコードを検討してください。

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;
    }
}

これはウィキペディアの例で、シングルトンの作成方法を説明しています。インスタンスはプライベート フィールドに保持され、コンストラクターはクラス外ではアクセスできません。メソッドはこの単一のインスタンスを返します。

コンストラクターについて:デフォルトでは、すべてのクラスにいわゆるデフォルト コンストラクターがあり、引数をとらず、単にスーパークラスの引数なしコンストラクターを呼び出します。スーパークラスに引数なしでアクセス可能なコンストラクターがない場合は、明示的なコンストラクターを作成する必要があります。

したがって、クラスにはコンストラクターが必要ですが、スーパークラスに引数のないコンストラクターがある場合は、それを記述する必要はありません。

于 2011-10-19T10:36:20.330 に答える
4

Joshua Bloch は、"Effective Java" という本の中で、enum を使用してシングルトンを実装することを推奨しています。

この質問を参照してください: Java でシングルトン パターンを実装する効率的な方法は何ですか?

于 2011-10-19T11:25:25.473 に答える