While Implementing Singleton the following things should be answered

  1. Reflection
  2. Serialization
  3. Cloning

Objects for Singleton Classes implemented using private Constructor can be invoked by Reflection as below

Item3.java

package com.mugil.org.ej;

import java.lang.reflect.Constructor;

public class Item3 {
	public static void main(String[] args) 
	{
		// reflection concept to get constructor of a Singleton class.  
		Constructor<Singleton> constructor;
		
		try {			
			constructor = Singleton.class.getDeclaredConstructor();
			
			// change the accessibility of constructor for outside a class object creation.
			constructor.setAccessible(true);
			
			// creates object of a class as constructor is accessible now.
			Singleton secondOb = constructor.newInstance();
			System.out.println(secondOb.getName());
			
			// close the accessibility of a constructor.
			constructor.setAccessible(false);
		} catch (Exception e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}


class Singleton {

    private static Singleton instance = new Singleton();

    /* private constructor */
    private Singleton() {}

    public static Singleton getDefaultInstance() {
        return instance;
    }
    
    public String getName()
    {
    	return "MyName";
    }
}

Output

MyName

Singleton and Serialization
Without readResolve() Method

// Java code to explain effect of 
// Serilization on singleton classes
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
class Singleton implements Serializable 
{
    // public instance initialized when loading the class
    public static Singleton instance = new Singleton();
     
    private Singleton() 
    {
        // private constructor
    }
}
 
 
public class GFG 
{
 
    public static void main(String[] args) 
    {
        try
        {
            Singleton instance1 = Singleton.instance;
            ObjectOutput out
                = new ObjectOutputStream(new FileOutputStream("file.text"));
            out.writeObject(instance1);
            out.close();
     
            // deserailize from file to object
            ObjectInput in 
                = new ObjectInputStream(new FileInputStream("file.text"));
             
            Singleton instance2 = (Singleton) in.readObject();
            in.close();
     
            System.out.println("instance1 hashCode:- "
                                                 + instance1.hashCode());
            System.out.println("instance2 hashCode:- "
                                                 + instance2.hashCode());
        } 
         
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }
}

Output

instance1 hashCode:- 1550089733
instance2 hashCode:- 785945

With readResolve() Method

// Java code to remove the effect of 
// Serialization on singleton classes
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
class Singleton implements Serializable 
{
    // public instance initialized when loading the class
    public static Singleton instance = new Singleton();
     
    private Singleton() 
    {
        // private constructor
    }
     
    // implement readResolve method
    protected Object readResolve()
    {
        return instance;
    }
}
 
public class GFG 
{
 
    public static void main(String[] args) 
    {
        try
        {
            Singleton instance1 = Singleton.instance;
            ObjectOutput out 
                = new ObjectOutputStream(new FileOutputStream("file.text"));
            out.writeObject(instance1);
            out.close();
         
            // deserailize from file to object
            ObjectInput in 
                = new ObjectInputStream(new FileInputStream("file.text"));
            Singleton instance2 = (Singleton) in.readObject();
            in.close();
         
            System.out.println("instance1 hashCode:- "
                                           + instance1.hashCode());
            System.out.println("instance2 hashCode:- "
                                           + instance2.hashCode());
        } 
         
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Output

instance1 hashCode:- 1550089733
instance2 hashCode:- 1550089733

Refer https://codethataint.com/blog/singleton-and-serialization/

// JAVA code to explain cloning 
// issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                           + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                           + instance2.hashCode()); 
  }
}

Output

Output :- 
instance1 hashCode:- 366712642
instance2 hashCode:- 1829164700

Two different hashCode means there are 2 different objects of singleton class.

To overcome this issue, override clone() method and throw an exception from clone method that is CloneNotSupportedException. Now whenever user will try to create clone of singleton object, it will throw exception and hence our class remains singleton.

// JAVA code to explain overcome 
// cloning issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    throw new CloneNotSupportedException();
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                         + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                         + instance2.hashCode()); 
  }
}

Output

Output:-
Exception in thread "main" java.lang.CloneNotSupportedException
	at GFG.Singleton.clone(GFG.java:29)
	at GFG.GFG.main(GFG.java:38)

If you don;t want to throw exception you can also return the same instance from clone method.

// JAVA code to explain overcome 
// cloning issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return instance;
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                           + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                           + instance2.hashCode()); 
  }
}

Output

Output:-
instance1 hashCode:- 366712642
instance2 hashCode:- 366712642

The Best way to implement Singleton is by using ENUM which takes care of Serialization and Other Issues on its own.

Singleton.java

public class Singleton 
{ 
    private static Singleton instance;   
 
    private Singleton() {}

    public static Singleton getInstance() 
    {
       if (instance == null) {
          instance = new Singleton();
       }
       return instance;
    }
}

In a Multi-threaded Environment

  1. Two Threads, Thread A and Thread B tries to access Object of Singleton class
  2. Thread A and B does call to Static getInstance() method
  3. Now when Thread A tries to do Null Check of instance instance == null chances of Thread B also entered the if block exists
    .
    .
    .
    if (instance == null) 
    {
      //Two threads may have passed the condition and might have got in
      instance = new Singleton();
    }
    .
    .
    .
    
  4. Now both the Threads have their own instance for the Singleton class.
  5. So there would be 2 instances of Singleton class at the end of if Block

Now there are many work arounds but DoubleCheckedLocking, Enum Singleton and Initialization On Demand Holder are the Optimized approach

Refer Table in Link

Method 1
In this method we does static block initialization of Singleton along with synchronized getInstance() method which allows the access to only one thread at a point of time.
Singleton.java

public class Singleton 
{
    private static Singleton instance;
 
    private Singleton() {}

    public static synchronized Singleton getInstance() 
    {
       if (instance == null) {
          instance = new Singleton();
       }
       return instance;
    }
}

But the above method is expensive since there is unnecessary locking and unlocking done every time the object get accessed.

Method 2(Double Checked Locking Singleton)
Instead of synchronizing the whole method lets synchronize the block of code which allows single thread to access the instance during the first time access.The consecutive thread would be served with the same thread allocated for the First thread once it is done with its task.

Singleton.java

public class Singleton 
{
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() 
    {
      if (instance == null) {
          synchronized(Singleton.class) {
             if (instance == null) {
                instance = new Singleton();
             }
          }
       }
       return instance;
    }
}

Other ways of achieving singleton are by using Eager Initialization and ENUM which has its own advantages and disadvantages.

In which scenario we should serialize a singleton?
Imagine you have a long-running app and want to be able to shut it down and later continue at the point where it was shut down (e.g. in order to do hardware maintenance). If the app uses a singleton that is stateful, you’d have to be able to save and restore the sigleton’s state, which is most easily done by serializing it.

Is it possible to serialize a singleton object?
2 Methods

  1. By using ENUM : ENUM implements Serializable by Default
  2. By adding implements Serializable to class to make it serializable, and delaring all instance fields transient (to prevent a serialization attack) and provide a readResolve method.

readResolve() method in Singleton Class implementing Serialization

.
.
// readResolve method to preserve singleton property
private Object readResolve() {
     // Return the one true Elvis and let the garbage collector
     // take care of the Elvis impersonator.
    return INSTANCE;
}
.
.

Why you need readResolve() Method
This method will be invoked when you will de-serialize the object. Inside this method, you must return the existing instance to ensure single instance application wide.

The Way serialization works is as below

Serializes the Object Property -> Stores to Persistent Storage
From Persistent Storage -> Creates new Object and Sets Properties of Object

The Object Before Serialization and after Serialization are not same. Only the Object Properties are same

Now lets take a simple Example where we serializes the PrintReport Class which has priority as one of its Object Variable.priority tells which should be given first preference while printing

PrintReport.java

package com.mugil.org;

import java.io.Serializable;

public class PrintReport implements Serializable {
    private static PrintReport instance = null;
	 
    public static PrintReport getInstance() {
        if (instance == null) {
            instance = new PrintReport();
        }
        return instance;
    }
    
    private transient int priority = 2;

	public int getPriority() {
		return priority;
	}
	
	public void setPriority(int priority) {
		this.priority = priority;
	}
}

Now when the above singleton which implements serialization gets called as below

PrintMedicalReport.java

package com.mugil.org;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class PrintMedicalReport 
{	
	 static PrintReport instanceOne = PrintReport.getInstance();
	 
	    public static void main(String[] args) {
	        try {
	            // Serialize to a file
	            ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
	                    "filename.ser"));
	            out.writeObject(instanceOne);
	            out.close();
	            
	            instanceOne.setPriority(1);
	            
	            // Serialize to a file
	            ObjectInput in = new ObjectInputStream(new FileInputStream(
	                    "filename.ser"));
	            PrintReport instanceTwo = (PrintReport) in.readObject();
	            in.close();
	 
	            System.out.println(instanceOne.getPriority());
	            System.out.println(instanceTwo.getPriority());
	 
	        } catch (IOException e) {
	            e.printStackTrace();
	        } catch (ClassNotFoundException e) {
	            e.printStackTrace();
	        }
	    }
}

Output

1
2

Note in the above code the instanceOne.setPriority(2); should have been called before out.writeObject(instanceOne).But that is not the case since the example explains the Object are different before and after Serialization.Only Object Properties(Metadata) are stored during serialization not the actual object.

You can see the Class Prints default Priority value in the output.

Now in context to singleton we want to maintain exactly one Object exist before and after serialization. Not with two object with same set of attributes.To achieve this we add readResolve() Method.

PrintReport.java

package com.mugil.org;

import java.io.Serializable;

public class PrintReport implements Serializable {
	private volatile static PrintReport instance = null;
	 
    public static PrintReport getInstance() {
        if (instance == null) {
            instance = new PrintReport();
        }
        return instance;
    }
    
    private int priority = 1;

	public int getPriority() {
		return priority;
	}
	
	public void setPriority(int priority) {
		this.priority = priority;
	}    
	     
    protected Object readResolve() {
        return instance;
    }   
}

Now when the PrintMedicalReport class gets executed the Output would be as below

Output

1
1

When you Serialize and Deserialize new file would be created and stored in disk every time.

In the above image by changing the filename.ser text you can change the attribute of objects serialized. This is known as Serialization attack. To overcome this you must declare all instance fields as transient.

Reference 2

Lets Consider the below Singleton code which uses Double Checked Locking

DoubleCheckLocking.java

public class DoubleCheckLocking 
{
    public static class SearchBox 
    {
        private static volatile SearchBox searchBox;

        //Private constructor
        private SearchBox() {}

        //Static method to get instance
        public static SearchBox getInstance() {
            if (searchBox == null) { // first time lock
                synchronized (SearchBox.class) {
                    if (searchBox == null) {  // second time lock
                        searchBox = new SearchBox();
                    }
                }
            }
            return searchBox;
        }
}

Lets dive deep into the code where Double Checking actually takes place

  if (searchBox == null) { // first time lock
                synchronized (SearchBox.class) {
                    if (searchBox == null) {  // second time lock
                        searchBox = new SearchBox();
                    }
                }
            }
  1. Lets say we have two threads A and B and lets assume that atleast one of them reaches line 3 and observes searchBox == null is true.
  2. Two threads can not both be at line 3 at the same time because of the synchronized block. This is the key to understanding why double-checked locking works.
  3. So, it must the case that either A or B made it through synchronized first. Without loss of generality, say that that thread is A. Then, upon seeing searchBox == null is true, it will enter the body of the statement, and set searchBox to a new instance of SearchBox. It will then eventually exit the synchronized block.
  4. Now it will be B’s turn to enter: remember, B was blocked waiting for A to exit. Now when it enters the block, it will observe searchBox. But A will have left just having set searchBox to a non-null value.

System is a class, that has a public static field out. So it’s more like

class System 
{
    public static PrintStream out;
}

class PrintStream
{
    public void println ...
}

This is a slight oversimplification, as the PrintStream class is actually in the java.io package, but it’s good enough to show the relationship of stuff.

A snapshot version in Maven is one that has not been released.

The idea is that before a 1.0 release (or any other release) is done, there exists a 1.0-SNAPSHOT. That version is what might become 1.0. It’s basically “1.0 under development”. This might be close to a real 1.0 release, or pretty far (right after the 0.9 release, for example).

The difference between a “real” version and a snapshot version is that snapshots might get updates. That means that downloading 1.0-SNAPSHOT today might give a different file than downloading it yesterday or tomorrow.

Usually, snapshot dependencies should only exist during development and no released version (i.e. no non-snapshot) should have a dependency on a snapshot version.

The snapshot is not necessarily more stable: it is just the latest build. The snapshot precedes the actual release, it does not come after it. Indeed, version numbers typically do not refer to branches

When you build an application, Maven will search for dependencies in the local repository. If a stable version is not found there, it will search the remote repositories (defined in settings.xml or pom.xml) to retrieve this dependency. Then, it will copy it into the local repository, to make it available for the next builds.

For example, a foo-1.0.jar library is considered as a stable version, and if Maven finds it in the local repository, it will use this one for the current build.

Now, if you need a foo-1.0-SNAPSHOT.jar library, Maven will know that this version is not stable and is subject to changes. That’s why Maven will try to find a newer version in the remote repositories, even if a version of this library is found on the local repository. However, this check is made only once per day. That means that if you have a foo-1.0-20110506.110000-1.jar (i.e. this library has been generated on 2011/05/06 at 11:00:00) in your local repository, and if you run the Maven build again the same day, Maven will not check the repositories for a newer version.

Maven provides you a way to can change this update policy in your repository definition:

<repository>
    <id>foo-repository</id>
    <url>...</url>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>XXX</updatePolicy>
    </snapshots>
</repository>

where XXX can be:

always – Maven will check for a newer version on every build;
daily – the default value;
interval:XXX – an interval in minutes (XXX)
never – Maven will never try to retrieve another version. It will do that only if it doesn’t exist locally. With the configuration, SNAPSHOT version will be handled as the stable libraries.

Updating Maven Snapshots are helpful during development where the maven first looks for local version of snapshot and adds to working set but still we get a build error we can force update snapshots which gets the snapshots from the repository

  1. Internally an ArrayList uses an Object[] Array.
           private transient Object[] elementData;
         
  2. As you add items to an ArrayList, the list checks to see if the backing array has room left. If there is room, the new item is just added at the next empty space. If there is not room, a new, larger, array is created, and the old array is copied into the new one.
  3. When we actually create an arrayList following piece of code is executed –
      this.elementData=new Object[initial capacity];
         
  4. ArrayList can be created in two ways-

    List<String> myList=new ArrayList<String>();
     
  5. When we create an ArrayList in this way, default constructor is invoked and will internally create an array of Object with default size, which is 10.

    List<String> myList=new ArrayList<String>(5);
     

    When we create an ArrayList in this way, constructor with an integer argument is invoked and will internally create an array of Object with the size, specified in the constructor argument, which happens to be 5 in this case.

  6. Inside add() method Check is made, before adding element into the array it will check what is the current size of filled elements and what is the maximum size of the array. If size of filled elements is greater than maximum size of the array then size of the array must be increased. But we know that the size of the array cannot be increased dynamically.

    So what happens internally is a new Array is created with size 1.5*currentSize and the data from old Array is copied into this new Array.

Internally an ArrayList uses an Object[].

Capacity vs Size

The capacity is how many elements the list can potentially accommodate without reallocating its internal structures.

The size is the number of elements in the list

If you allocate a new array with arr = new Employee[100], the size of that array (arr.length) is going to be 100. It has 100 elements. All the elements are initially null (as this is an array of object references), but still, there are 100 elements.

If you do something like list = new ArrayList (100), and try to check list.size(), you’ll get 0. There are no elements in the list.

Internally, it’s true that the ArrayList allocates enough place to put 100 items before it needs to extend its capacity, but that’s an internal implementation detail, and the list presents its content to you as “no items stored”. Only if you actually do list.add(something), you’ll have items in the list.

So although the list allocates storage in advance, the API with which it communicates with the program tells you there are no items in it. The null items in its internal array are not available to you – you cannot retrieve them or change them.

An ArrayList is just one way to represent an abstract list, and the capacity of an ArrayList is an implementation detail of how the system implements the logical list.

An ArrayList stores the elements of a list by using an actual array “under the covers.” The actual realization of the array in computer memory has a certain size when it is allocated; this size is the ArrayList’s capacity. The ArrayList emulates a variable-sized list by storing the logical length of the list in addition to the fixed-length array. Thus if you have an ArrayList with a capacity 10 which contains 4 logical elements, the ArrayList can be represented as a length and an array

(4) | e1 | e2 | e3 | e4 | __ | __ | __| __ | __ | __ |

where the (4) is the logical length of the list and ‘__’ represent data that is ignored because it is not part of the logical list. If you attempt to access the 5th element of this ArrayList, it will throw an exception because it knows that the fifth element has not been initialized. If we then append an extra element e5 to the list, the ArrayList becomes

(5) | e1 | e2 | e3 | e4 | e5 | __ | __ | __ | __ | __ |

Note that the capacity has not changed, while the logical length has, because the underlying array is still able to handle all the data in the logical list.

If you manage to add more than ten elements to this list, the ArrayList will not break. The ArrayList is an abstraction meant to be compatible with all array operations. Rather, the ArrayList changes its capacity when its logical length exceeds its original capacity. If we were to add the elements (a1, a2, …, a7) to the above list, the resulting ArrayList might look like

(12) | e1 | e2 | e3 | e4 | e5 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | __ | __ | __ | __ | __ | __ | __ | __ |

with a capacity of 20.

Once you have created an ArrayList, you can ignore the capacity in all programming that follows; the logic is unaffected. However, the performance of the system under certain kinds of operations can be affected. Increasing the capacity, for instance, might well involved allocating a larger array, copying the first array into the second and then performing the operations. This can be quite slow compared to, e.g. the same operation on a linked list. Thus it is sensible to choose the capacity of an ArrayList to be bigger than, or at least comparable to, the actual number of elements expected in the real runtime environment.

Is there a Way to Create ArrayList of Fixed size in Java

 List<String> fixedSizeList = Arrays.asList(new String[100]);

You cannot insert new Strings to the fixedSizeList (it already has 100 elements). You can only set its values like this:

fixedSizeList.set(7, "new value");

What would be the Output of the Following Code

List<Employee> employees = new ArrayList<>(100);
int size = employes.size();

size will be 0 while the initial capacity is 100.

Yes. An interface can extend multiple interfaces, as shown here:

interface Maininterface extends inter1, inter2, inter3{  
  // methods
}

A single class can also implement multiple interfaces

interface A
{
    void test();
}

interface B 
{
    void test();
}

class C implements A, B
{
    @Override
    public void test() {

    }     
}

Single implementation works for both.

Yes.You can use any kind of method in an abstract class

public abstract class AbstractDAO{

public void save(){
  validate();
  //save
}
  private void validate(){ // we are hiding this method
  }
}

Private Constructors
If Private constructor is the only constructor of the class, then the reason is clear: to prevent subclassing. Some classes serve only as holders for static fields/methods and do not want to be either instantiated or subclassed. Note that the abstract modifier is in this case redundant—with or without it there would be no instantiation possible. The abstract modifier is also bad practice because it sends wrong signals to the class’s clients. The class should in fact have been final.

Abstract Class with Private Constructor is same as Final Class. Both serves the same purpose.

Q1.What is the difference between Singleton vs Factory pattern?
A singleton pattern ensures that you always get back the same instance of whatever type you are retrieving, whereas the factory pattern generally gives you a different instance of each type.

The purpose of the singleton is where you want all calls to go through the same instance. An example of this might be a class that manages a disk cache, or gets data from a static dictionary; wherever it is important only one known instance interacts with the resource. This does make it less scalable.The purpose of the factory is to create and return new instances. Often, these won’t actually be the same type at all, but they will be implementations of the same base class. However, there may be many instances of each type

Q2.How to stop create instance via Reflection in Singleton

private Singleton() {
    if (singleton != null) {
        throw new IllegalStateException("Singleton already constructed");
    }
}

Q3.What are different ways of preventing object creation in singleton?
There are 5 ways of creating Objects. The below code explains how to prevent object creation by all 5 methods. Instead of
doing all these we can create singleton by using ENUM
Singleton.java

public class Singleton implements Serializable 
{
 private static final long serialVersionUID = 3119105548371608200 L;
 private static final Singleton singleton = new Singleton();
 
 //Prevents Class creation by Constructor
 private Singleton() 
 {
     //Prevents Object creation by reflection
     if( Singleton.singleton != null ) 
     {
        throw new InstantiationError( "Creating of this object is not allowed." );
     }
 }
 
 public static Singleton getInstance() 
 {
  return singleton;
 }
 
 //Prevents Class creation during cloning
 @Override
 protected Object clone() throws CloneNotSupportedException 
 {
  throw new CloneNotSupportedException("Cloning of this class is not allowed");
 }
 
 //Prevents New Object Creation by returning same singleton object
 protected Object readResolve() 
 {
  return singleton;
 }
}

Main.java

try {
    Class<Singleton> singletonClass = (Class<Singleton>) Class.forName("test.singleton.Singleton");
    Singleton singletonReflection = singletonClass.newInstance();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (CloneNotSupportedException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}