Что такое Java-эквивалент объекта Scala? - PullRequest
12 голосов
/ 19 октября 2011

В Scala мы можем написать

object Foo { def bar = {} }

Как это реализовано компилятором?Я могу вызвать 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();
      ()
    }
  }
}

Ответы [ 3 ]

22 голосов
/ 19 октября 2011

При компиляции кода компилятор 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 предоставляет метод static для взаимодействия с Java.

11 голосов
/ 19 октября 2011

Поддержка синглетонов не на уровне языка, но язык предоставляет достаточно возможностей для их создания без проблем.

Рассмотрим следующий код:

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

Это пример из Википедии, который объясняет, как можно сделать синглтон.Экземпляр хранится в закрытом поле, конструктор недоступен вне класса, метод возвращает этот единственный экземпляр.

Что касается конструкторов: каждый класс по умолчанию имеет так называемый конструктор по умолчанию , который не принимает аргументов и просто вызывает конструктор суперкласса без аргументов.Если у суперкласса нет доступного конструктора без аргументов, вам придется написать явный конструктор.

Таким образом, класс должен иметь конструктор, но вам не нужно писать его, если у суперкласса естьконструктор без аргументов.

4 голосов
/ 19 октября 2011

Джошуа Блох в книге «Эффективная Java» рекомендовал использовать перечисление для реализации синглтона.

См. Этот вопрос: Как эффективен способ реализации одноэлементного шаблона в Java?1004 *

...