7

The standard method of implementing singleton design pattern is this:

public class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    private Singleton() {}
}

I was wondering if you could also implement it like this:

public class Singleton {
    private Singleton() {}
    public final static Singleton INSTANCE = new Singleton();
}

and if yes which version is better?

Mat.S
  • 1,814
  • 7
  • 24
  • 36
  • possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – Paul Vargas Aug 13 '13 at 05:02

4 Answers4

10

Neither. In both cases, a trusted consumer can invoke the private constructor via reflection. An additional problem is that it these implementation don't play nicely with serialization unless you take extra steps to make it so (by default, if you take the naïve approach, every time a Singleton is deserialized, it will create a new instance).

The correct solution is to use an enum that defines a single value.

public enum Singleton {
    INSTANCE;

    // methods
}

From Effective Java:

While this approach is yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

jason
  • 236,483
  • 35
  • 423
  • 525
  • Huh. That's pretty cool. When are enum values initialized? Does this solve all the concurrency problems that the `SingletonHolder` technique solves? – Jason C Aug 13 '13 at 05:07
  • 1
    @Jason C: When the `enum` class is initialized, very much like when the `static` initializer is run for `static` members. Yes, it solves all the concurrency problems as again it's basically the same as `static` initializers. – jason Aug 13 '13 at 05:11
1

Why you not use enum for realisation Singleton?

 public enum SingletonEnum {
     Instance;
     private static String testStr = "";

     public static void setTestStr(String newTestStr) {
         testStr = newTestStr;
     }

     public static String getTestStr() {
         return testStr;
     }

     public static String sayHello(String name) {
         return "Hello " + name;
     }
 }
Rinat Mukhamedgaliev
  • 5,401
  • 8
  • 41
  • 59
0

In my opinion first one is better as it looks more aligned to Object oriented approach.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
0

While there's nothing particularly wrong with either solution, this solution from Wikipedia should give you the best compatibility and give you a thread-safe singleton:

University of Maryland Computer Science researcher Bill Pugh has written about the code issues underlying the Singleton pattern when implemented in Java.[11] Pugh's efforts on the "Double-checked locking" idiom led to changes in the Java memory model in Java 5 and to what is generally regarded as the standard method to implement Singletons in Java. The technique known as the initialization on demand holder idiom, is as lazy as possible, and works in all known versions of Java. It takes advantage of language guarantees about class initialization, and will therefore work correctly in all Java-compliant compilers and virtual machines. The nested class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).

public class Singleton {
        // Private constructor prevents instantiation from other classes
        private Singleton() { }

        /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
        private static class SingletonHolder { 
                public static final Singleton INSTANCE = new Singleton();
        }

        public static Singleton getInstance() {
                return SingletonHolder.INSTANCE;
        }
}
James McCracken
  • 15,488
  • 5
  • 54
  • 62
  • `private` constructor doesn't prevent instantiation by a trusted consumer who can use reflection to get a handle to the constructor. – jason Aug 13 '13 at 05:01
  • 2
    A trusted consumer who uses reflection to invoke the constructor of a class named `Singleton` should expect the unexpected. – Jason C Aug 13 '13 at 05:03