Today in my interview one interviewer asked me to write a Singleton class. And i gave my answer as
public class Singleton {
private static Singleton re
As others have already pointed out, the enum pattern is now widely considered a better approach to the Singleton vs. the old-school method, but I just wanted to point out a drawback.
We had a Singleton in the form of:
public enum Foo {
INSTANCE;
}
that had been around for awhile, working just fine. Then during a code review, we saw this:
public enum Foo {
INSTANCE,
ANOTHER;
}
After we smacked him across the face with a wet mackerel, the coder in question had seen the error of his ways, and a larger than small amount of code had to be backed out and/or rewritten. Yes, we caught it before it went out into production, but work had to be done to erase it.
I feel that this a weakness of this type of Singleton (albeit small and perhaps rare) vs. the old-school way. Yes, you can break any pattern by implementing it wrong, but it seems a whole heck of a lot easier for a coder to break an enum Singelton than a well-formed old-school Singleton.
EDIT:
For completeness, here's an enum Singleton that guards against additional values getting added later:
public enum Foo
{
INSTANCE;
// adding another type here will cause a runtime
static
{
if (Foo.values().length != 1)
{
throw new IllegalStateException("Not a Singleton.");
}
}
}
Why can't you do just
public class SingletonSandBox {
private static SingletonSandBox instance = new SingletonSandBox();
private SingletonSandBox(){
}
public static SingletonSandBox getInstance(){
return instance;
}
}
and test
public static void main(String[] args) {
SingletonSandBox sss1 = SingletonSandBox.getInstance();
SingletonSandBox sss2 = SingletonSandBox.getInstance();
System.out.println(sss1 == sss2);
}
As I know this is thread-safe and shorter than using static block. Again static field declaration is read earlier comparing to static block by the runtime.
You can do
public enum Singleton {
INSTANCE;
}
and for a utility class which has no instances
public enum Utility {
;
public static void method();
}
A thread safe version of the OPs initial approach, plus no one else dared to suggest a synchronized statement.
final class Singleton
{
private static Object lock = new Object();
private static volatile Singleton instance = null;
private Singleton() { }
public static Singleton getInstance()
{
if(instance == null)
{
synchronized(lock)
{
if(instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
This is because your solution is not threadsafe.
The modern way is to tie the instance to an enum
value:
enum Singleton {
INSTANCE;
}
If you want to use lazy init of the instance then you can use the ClassLoader
to guarantee thread safety:
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
public static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
More information on Wikipedia
The Singleton I'd write would look like this:
@Service
class PersonService {
// implementation here
}
But I also like the enum ideas. In reality, I never write (nor need) a Singleton other than one like the one above.