Что такое Java-эквивалент объекта Scala?
В Scala мы можем написать
object Foo { def bar = {} }
Как это реализуется компилятором? Я могу вызвать Foo.bar();
С Java
но new Foo();
из Java выдает ошибку cannot find symbol symbol: constructor Foo()
- поддерживает ли СПМ синглетоны изначально?
- можно ли иметь класс в 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 ответа:
Поддержка синглетов не находится на уровне языка, но язык предоставляет достаточно возможностей для их создания без каких-либо проблем.
Рассмотрим следующий код:
Это пример из Википедии, который объясняет, как можно сделать синглтон. Экземпляр хранится в закрытом поле, конструктор недоступен вне класса, метод возвращает этот единственный экземпляр.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
предоставляет методstatic
для взаимодействия с Java.
Джошуа блох в книге "эффективная Java" рекомендовал использовать перечисление для реализации синглетона.
См. этот вопрос: каков эффективный способ реализации синглетного шаблона в Java?