Em Scala, podemos escrever
object Foo { def bar = {} }
Como isso é implementado pelo compilador? Eu posso ligar Foo.bar();
de Java mas new Foo();
do Java dá o erro cannot find symbol symbol: constructor Foo()
- A JVM suporta singletons nativamente?
- É possível ter uma classe em Java que não tenha um construtor?
Nota: aqui está a saída do código por scalac -print
package <empty> {
final class Foo extends java.lang.Object with ScalaObject {
def bar(): Unit = ();
def this(): object Foo = {
Foo.super.this();
()
}
}
}
Respostas:
11 para resposta № 1Suporte para singletons não está em um nível de linguagem, mas a linguagem fornece recursos suficientes para criá-los sem nenhum problema.
Considere o seguinte código:
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;
}
}
Este é um exemplo da Wikipedia, que explicacomo um singleton pode ser feito. Uma instância é mantida em um campo privado, o construtor está inacessível fora da classe, o método retorna esta única instância.
Quanto aos construtores: cada classe por padrão tem um assim chamado construtor padrão que não aceita argumentos e simplesmente chama oconstrutor no-args da superclasse. Se a superclasse não tiver nenhum construtor acessível sem argumentos, você terá que escrever um construtor explícito.
Portanto, uma classe deve ter um construtor, mas você não precisa escrevê-la se a superclasse tiver um construtor sem args.
21 para resposta № 2
Ao compilar seu código, o compilador Scala produz um equivalente do seguinte código 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()
}
}
Aqui Foo$
é uma implementação real de um singleton, enquanto Foo
Fornece uma static
método para interação com Java.
4 para resposta № 3
Joshua Bloch recomendou no livro "Effective Java" o uso de um enum para implementar um singleton.
Veja esta pergunta: O que é uma maneira eficiente de implementar um padrão singleton em Java?