Item 3. Enforce the Singleton

Enforce the singleton property with a private constructor or an enum type.

Singletons are intrinsically unique.  They often represent a system component or object that never changes throughout the life of the application.   The best way to implement a singleton is with a single element enumeration:

// Enum singleton - the preferred approach 
public enum HoundDog {     
     INSTANCE;
     public boolean cryingAllTheTime() { return true; } 

}

Using an enumeration is equivalent to the public field approach and it supports proper serialization for a singleton.

The public field approach.

// Singleton with public final field 
public class HoundDog {     
     public static final HoundDog INSTANCE = new HoundDog();     
     private HoundDog() { ... }     
     public boolean cryingAllTheTime() { return true; } 

}

The static factory approach:

// Singleton with static factory 
public class Hotel {     
     private static final Hotel INSTANCE = new Hotel();    
     private Hotel() { ... }
     public static Hotel getInstance() { return INSTANCE; }
     public String name(){ return "Heartbreak Hotel"; }
}

If the singleton is serializable (see the section on Serialization), you must declare all singleton fields transient and provide a ReadResolve method (Item #77).

Advantages

  1. Bloch invented the coolest word ever to describe singletons: monoelvistic.
  2. of the public field approach: declarations make clear the class is a singleton.
  3. See item #27 for an additional advantage.

Disadvantages

  1. it can’t usually (never say never) be substituted, making it difficult to test the classes that use the singleton.

My Own Additional Notes

Bloch points out that many JVMs inline the call to the static factory method, making the final field form and the factory method form equal in performance.  While this may be true, the operation to read a field is atomic and will always perform slightly better than a call to a static factory.  This can be an important difference on a mobile device.

If you can avoid hanging on to copies of the singleton you will also save a bit of memory:

public class Foo {

     /*
      * holding on to an extra instance of the singleton 
      * for the entire life of the class is not preferred.
      * It requires slightly more space on the heap:
      * 4 extra bytes per instance of Foo on a 32 bit processor
      * and 8 extra bytes on a 64 bit processor.
      */
      private HoundDog instance = HoundDog.INSTANCE;
      public static void bar(){
            if (instance.cryingAllTheTime()) { ... }
      }

      /*
       * function bar2() saves a bit of memory compared to bar() - 
       * important on an embedded like Android or Blackberry.  
       * It may also reduce garbage collection, which can become 
       * so costly it slows own the application itself.
       */
       private static void bar2(){
            if (HoundDog.INSTANCE.cryingAllTheTime()) { ... }
       }

You can expect to realize better overall application performance with final field form especially in cases where the application needs the singleton many thousand times, or repeatedly in a block of code that must run fast (e.g. graphics processing).

One thought on “Item 3. Enforce the Singleton

  1. Pingback: Effective Java #3: Be Monoelvistic like the Singleton | Richard's Mobile Blog

And now it's your turn ... comment here or on Twitter (@Androider)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s