How To Develop Singleton Java Class

Posted By : Amarjeet Kumar | 28-Oct-2018
This post is all about having the clear idea about developing a Singleton Java Class. In this post,
I will be explaining step by step about How to develop a Singleton Java Class with Sample Java
Code to have the clear idea about the concepts.This post will be covering various factors like
How to make your Singleton Java Class as 
(a) Clone method proof Java Class.
(b) Reflection API proof Java Class.
(c) Thread safe Java Class.
(d) De-Serialization Proof Java Class.
 
Rules to Develop Singleton Java Class :
 
1.  Declare a private static reference variable to hold current class Object. This reference will hold null only
     for the first time after it will refer to the object forever (till the JVM terminates). This reference should be
     initialized using the static factory method as discussed in step 3.

  
 class PrinterUtil {
     private static PrinterUtil instance = null;
    }
    
2. We must declare all the constructor as private so that its object cannot be created from outside of the class using
    new keyword.

     
 class PrinterUtil {
      private static PrinterUtil instance = null;
      private  PrinterUtil(){
      System.out.println("PrinterUtil()");
      }
      }
  
3. We must develop a static final factory method, which will return a new object only for the first time
    and the same object will be returned then after. Since we have an only private constructor,we can
    not use a new keyword from outside of the program we must declare this method as static,so it can
    be accessed directly using the class name. Declare this method as final so that the child class cannot
    override this method and change the default behavior.

        
public static final PrinterUtil newInstance(){
      if(instance==null)
      instance = new PrinterUtil();
      return instance;
     }
  
4. Make your singleton class Reflection API proof.

  
public class PrinterUtil{
     private static boolean isNew=true; 
    // 1st time -true, 2nd time=-false, Used for Reflection Api proof and Multi-Thread double check

    private PrinterUtil(){
    // To prevent Reflection Api creating Multiple Objects
    if(isNew){
    isNew=false;
    System.out.println("PrinterUtil()");
    }
    else
   {
    throw new InstantiationError("Can not create Multiple Object");
   }
 
5. Make your factory method Thread Safety, so that only one object is created even if more than one
    thread tries to call this method simultaneously. Declare the whole method as the synchronized
    method or use synchronized block.
 
  public static final PrinterUtil getInstance(){
      if(instance==null){
      synchronized(PrinterUtil.class){
      if(instance==null){
      instance=new PrinterUtil();
      }
      }
      }
      return instance;
     }
      

Note:-  Instead of making the whole factory method as the synchronized method, it is good to place
            only the condition check part in the synchronized block.

   
  public static final PrinterUtil getInstance(){
      if(instance==null){
      synchronized(PrinterUtil.class){
      if(instance==null){
      instance=new PrinterUtil();
      }
      }
      }
      return instance;
     }
 
6. Prevent your Singleton Object from De-Serialization.

  
 public class PrinterUtil{
   private static PrinterUtil instance=null;

   private PrinterUtil(){
   System.out.println("PrinterUtil()");
   }

   protected Object readResolve(){
   System.out.println("readResolve()");
   return instance;
   }
   }
 
7. Prevent your singleton object from cloning.

    
public class PrinterUtil{
   private static PrinterUtil instance=null;

   private PrinterUtil(){
   System.out.println("PrinterUtil()");
   }

   @Override
   public Object clone() throws CloneNotSupportedException {
   throw new CloneNotSupportedException();
   }
   }
 
8. Use static-block or static definition.

 
 public class PrinterUtil{
  private static PrinterUtil instance = new PrinterUtil(); // static dafinition

  // OR
  /*
  private static  PrinterUtil instance =null;
  static{
  instance=new PrinterUtil();
  }
  */
  private PrinterUtil(){
  System.out.println("PrinterUtil()");
  }
  public static final PrinterUtil getInstance(){
  return instance;
  }
  }
 
Conclusion : 
This post will be very much helpful in situation where you need to create a Singleton Java Class.
 
 

About Author

Author Image
Amarjeet Kumar

He is working as Associate Consultant-Development on BlockChain Project.

Request for Proposal

Name is required

Comment is required

Sending message..