Singleton with subclassing in java - java

The most common way of implementing a singleton in java is to use a private constructor with a public accessor method of the form --
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
However, since the constructor is private, it prevents subclassing the singleton. Is there any way in which we can make a singleton which allows subclassing ?

When you have a class A extends B, an instance of A essentially "includes" instance of B. So the very concept of inheritance is contrary to the singleton model.
Depending on what you need it for, I would consider using composition / delegation. (A would have a reference to the singleton, rather than extending its class). If you need inheritance for some reason, create an interface with the Singleton methods, have Singleton implement that interface, and then have another class also implement that interface, and delegate to the singleton for its implementation of the relevant methods.

If you can inherit it, it's not really a singleton, since each inherited class will have at least one instance.
However, you can just make the constructor protected.

I respectfully offer a counterpoint to the comments that suggest a singleton should not be subclassed. Subclassing a singleton is discussed in "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson, and Vlissides (aka "The Gang of Four" book or "GOF" for short).
A properly subclassed singleton would also be a singleton. For example, suppose you have a singleton that handles logging informational messages called Logger. Now suppose you want to extend the functionality of Logger to write output using HTML tags. Let's call it HTMLLogger. Both of these classes are singletons, but one extends the functionality of the other.
First, here's a simple singleton and its test case:
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.simple;
public class SimpleSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static SimpleSingleton instance;
private int sampleValue;
public static SimpleSingleton getInstance() {
if (instance == null) {
instance = new SimpleSingleton();
}
return instance;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected SimpleSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.simple.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.simple.SimpleSingleton;
public class SimpleSingletonTest {
#Test
public void testIllegalCreation() {
// The following line will not compile because the constructor is not visible.
// Singleton instance = new Singleton();
}
#Test
public void testObjectEquality() {
SimpleSingleton instance1 = SimpleSingleton.getInstance();
assertNotNull(instance1);
SimpleSingleton instance2 = SimpleSingleton.getInstance();
assertNotNull(instance2);
assertEquals(instance1, instance2);
}
#Test
public void testDataEquality() {
SimpleSingleton instance1 = SimpleSingleton.getInstance();
assertNotNull(instance1);
SimpleSingleton instance2 = SimpleSingleton.getInstance();
assertNotNull(instance2);
assertEquals(instance1, instance2);
instance1.setSampleValue(5);
int testSampleValue = instance2.getSampleValue();
assertEquals(testSampleValue, 5);
}
}
/////////////////////////////////////////////////////////////////////////////
I've found four ways you can subclass a singleton.
Option 1. Brute force.
Essentially, the subclass reimplements the key features to make the class a singleton. That is, the static instance variable, the static getInstance method, and a hidden constructor. In this case, the hidden constructor calls the base class.
Here's a sample base class, subclass, and test case:
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce;
// This singleton can be extended (subclassed)
public class BruteForceExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static BruteForceExtendableSingleton instance;
private int sampleValue;
public static BruteForceExtendableSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
instance = new BruteForceExtendableSingleton();
}
return instance;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected BruteForceExtendableSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce;
public class BruteForceSubclassSingleton extends BruteForceExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static BruteForceSubclassSingleton instance;
private int sampleValue2;
public static BruteForceSubclassSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
instance = new BruteForceSubclassSingleton();
}
return instance;
}
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
protected BruteForceSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassbruteforce.BruteForceExtendableSingleton;
import study.design.patterns.creational.singleton.subclassbruteforce.BruteForceSubclassSingleton;
public class BruteForceExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// BruteForceExtendableSingleton instance = new BruteForceExtendableSingleton();
// BruteForceSubclassSingleton instance2 = new BruteForceSubclassSingleton();
}
#Test
public void testCreateBruteForceExtendableSingleton() {
BruteForceExtendableSingleton singleton = BruteForceExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof BruteForceExtendableSingleton);
assertFalse(singleton instanceof BruteForceSubclassSingleton);
}
#Test
public void testCreateBruteForceSubclassSingleton() {
BruteForceExtendableSingleton singleton = BruteForceSubclassSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a BruteForceSubclassSingleton.
assertTrue(singleton instanceof BruteForceSubclassSingleton);
}
#Test
public void testCreateBothBruteForceSingletons() {
BruteForceExtendableSingleton singleton = BruteForceExtendableSingleton.getInstance();
assertNotNull(singleton);
assertTrue(singleton instanceof BruteForceExtendableSingleton);
assertFalse(singleton instanceof BruteForceSubclassSingleton);
BruteForceExtendableSingleton singleton2 = BruteForceSubclassSingleton.getInstance();
assertNotNull(singleton2);
assertTrue(singleton2 instanceof BruteForceSubclassSingleton);
assertFalse(singleton == singleton2);
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Allows for both singletons to exist at the same time.
Cons:
Duplication of effort to create a singleton. The singleton nature of the subclass does not come from its base class.
If the singletons need to be separate, it's possible that a better design is needed to share the other methods instead of subclassing.
Option 2. Selecting from a fixed set of classes.
In this case, the getInstance method in the base class determines which instance to use based on a flag, such as a system property. In the code sample, I use the name of the class itself. Using a series of if blocks, the code decides how to initialize the instance.
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed;
// This singleton can be extended (subclassed)
public class FixedExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static FixedExtendableSingleton instance;
private int sampleValue;
public static FixedExtendableSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
if (singletonName.equals(FixedExtendableSingleton.class.getSimpleName())) {
instance = new FixedExtendableSingleton();
} else if (singletonName.equals(FixedSubclassSingleton.class.getSimpleName())) {
instance = new FixedSubclassSingleton();
}
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected FixedExtendableSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed;
public class FixedSubclassSingleton extends FixedExtendableSingleton {
private int sampleValue2;
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected FixedSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassfixed.FixedExtendableSingleton;
import study.design.patterns.creational.singleton.subclassfixed.FixedSubclassSingleton;
public class FixedExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// ExtendableSingleton instance = new ExtendableSingleton();
// FixedSubclassSingleton instance = new FixedSubclassSingleton();
}
#Test
public void testCreateExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FixedExtendableSingleton");
FixedExtendableSingleton singleton = FixedExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof FixedExtendableSingleton);
assertFalse(singleton instanceof FixedSubclassSingleton);
}
#Test
public void testCreateFixedSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FixedSubclassSingleton");
FixedExtendableSingleton singleton = FixedExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a FixedSubclassSingleton.
assertTrue(singleton instanceof FixedSubclassSingleton);
}
#AfterEach
protected void tearDown() {
FixedExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Clearer binding of subclass to singleton behavior.
Reduction of duplicate code.
Cons:
Only a fixed set of subclasses are defined. Adding a new subclass requires modifying the getInstance method.
Option 3. Determine which singleton to use from a dynamic set of classes.
This method attempts to remove the need to modify getInstance for every subclass. The idea is to include a registry (map) of names to singletons in the base class, and look up the correct one in getInstance.
In order to populate the registry with singletons, each singleton needs to be created beforehand. How is this done? According to GOF, we can assign a static variable to an instance of the object. When the class is loaded, the singleton is constructed, and the constructor adds the object to the registry. This is more complex, but it works (sort of).
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible;
import java.util.HashMap;
import java.util.Map;
//This singleton can be extended (subclassed)
public class FlexibleExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static FlexibleExtendableSingleton instance;
// This must appear before thisSingleton, because the constructor requires the registry.
protected static Map<String, FlexibleExtendableSingleton> registry = new HashMap<String, FlexibleExtendableSingleton>();
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static FlexibleExtendableSingleton thisSingleton = new FlexibleExtendableSingleton();
public static void activateClass() {
// Do nothing special.
}
private int sampleValue;
protected static void register(String name, FlexibleExtendableSingleton singletonClass) {
registry.put(name, singletonClass);
}
protected static FlexibleExtendableSingleton lookupFromRegistry(String name) {
return registry.get(name);
}
public static FlexibleExtendableSingleton getInstance() {
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
instance = lookupFromRegistry(singletonName);
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected FlexibleExtendableSingleton() {
// Protected insures construction cannot occur outside of class.
// Register the class when it is constructed by its static method.
// Subclasses will be able to use this method as well.
register(this.getClass().getSimpleName(), this);
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadExtendableSingleton;
public class FlexibleSubclassSingleton extends FlexibleExtendableSingleton {
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static FlexibleSubclassSingleton thisSingleton = new FlexibleSubclassSingleton();
private int sampleValue2;
public static void activateClass() {
// Do nothing special.
}
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected FlexibleSubclassSingleton() {
// The following line will also register the class.
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassflexible.FlexibleExtendableSingleton;
import study.design.patterns.creational.singleton.subclassflexible.FlexibleSubclassSingleton;
public class FlexibleExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// FlexibleExtendableSingleton instance = new FlexibleExtendableSingleton();
// FlexibleSubclassSingleton instance2 = new FlexibleSubclassSingleton();
}
#Test
public void testCreateFlexibleExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FlexibleExtendableSingleton");
FlexibleExtendableSingleton.activateClass();
FlexibleSubclassSingleton.activateClass();
FlexibleExtendableSingleton singleton = FlexibleExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof FlexibleExtendableSingleton);
assertFalse(singleton instanceof FlexibleSubclassSingleton);
}
#Test
public void testCreateFlexibleSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FlexibleSubclassSingleton");
FlexibleExtendableSingleton.activateClass();
FlexibleSubclassSingleton.activateClass();
FlexibleExtendableSingleton singleton = FlexibleExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a FlexibleSubclassSingleton.
assertTrue(singleton instanceof FlexibleSubclassSingleton);
}
#AfterEach
protected void tearDown() {
FlexibleExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Notice the method "activateClass" in each of the singletons. This method is empty and appears to do nothing. In reality, it is there to trigger loading the class for the first time. When called, the class is loaded, which creates the static singleton instance, which adds the entry to the registry. If the class is not loaded, the registry will not be populated and getInstance will return null for any class except for the base class, because calling getInstance will also trigger loading the base class.
Alternatively, instead of using "activateClass" methods, you could use a ClassLoader to load all of the singleton classes. You would still need to explicitly load every singleton class.
Pros:
getInstance does not have to be modified each time.
Cons:
Every subclass requires an empty activateClass method (or another way to load the class), which must be called prior to getInstance. Since each singleton class must be activated, we didn't gain much improvement from Option 2.
Option 4. Dynamically loading the singleton by name.
In Option 3 above, we had the problem of loading the singleton classes to populate a registry. Since the selection of the singleton is already being controlled by a system property, why not just load the singleton class to be used and set that as the instance?
Using reflection, we can load the class by name, locate the static singleton (the "thisSingleton" field), and assign it to the instance.
NOTE: Reflection enables a developer to bypass encapsulation, so should be used with caution. In this case, its use is limited to getInstance.
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload;
import java.lang.reflect.Field;
//This singleton can be extended (subclassed)
public class DynamicLoadExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static DynamicLoadExtendableSingleton instance;
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static DynamicLoadExtendableSingleton thisSingleton = new DynamicLoadExtendableSingleton();
private int sampleValue;
public static DynamicLoadExtendableSingleton getInstance() {
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
ClassLoader loader = DynamicLoadExtendableSingleton.class.getClassLoader();
try {
Class<?> singletonClass = loader.loadClass(singletonName);
Field field = singletonClass.getDeclaredField("thisSingleton");
field.setAccessible(true);
instance = (DynamicLoadExtendableSingleton) field.get(null);
} catch (ClassNotFoundException e) {
// The class was not found.
// TODO: Add error handling code here.
} catch (NoSuchFieldException e) {
// The field does not exist - fix the singleton class to include thisSingleton field.
// TODO: Add error handling code here.
} catch (IllegalAccessException e) {
// Should not occur - we make the field accessible just for this purpose.
// TODO: Add error handling code here.
}
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected DynamicLoadExtendableSingleton() {
// Protected insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload;
public class DynamicLoadSubclassSingleton extends DynamicLoadExtendableSingleton {
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static DynamicLoadSubclassSingleton thisSingleton = new DynamicLoadSubclassSingleton();
private int sampleValue2;
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected DynamicLoadSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadExtendableSingleton;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadSubclassSingleton;
public class DynamicLoadExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// DynamicLoadExtendableSingleton instance = new DynamicLoadExtendableSingleton();
// DynamicLoadSubclassSingleton instance2 = new DynamicLoadSubclassSingleton();
}
#Test
public void testCreateDynamicLoadExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", DynamicLoadExtendableSingleton.class.getName());
DynamicLoadExtendableSingleton singleton = DynamicLoadExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof DynamicLoadExtendableSingleton);
assertFalse(singleton instanceof DynamicLoadSubclassSingleton);
}
#Test
public void testCreateDynamicLoadSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", DynamicLoadSubclassSingleton.class.getName());
DynamicLoadExtendableSingleton singleton = DynamicLoadExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a DynamicLoadSubclassSingleton.
assertTrue(singleton instanceof DynamicLoadSubclassSingleton);
}
#AfterEach
protected void tearDown() {
DynamicLoadExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Subclasses do not require a method to activate the class. The only code required is a "thisSingleton" field.
The getInstance method does not require modification for each new subclass.
Cons:
Reflection can be slower, but since it's only used in one place and only when the singleton is assigned, the risk is minimal.
It's possible to get an error if the class name is incorrect. Again, this is a minimal risk.
In summary, while subclassing a singleton may not be common, it is addressed in the GOF book as feasible. There are a few ways to support subclassing singletons, each with benefits and drawbacks. Some of the methods listed above come directly from the book. The method of using reflection was my addition.

Are you looking to provide some inheritable behavior to a number of singleton's? If so, perhaps you could move that code into an abstract class.
As SLaks pointed out, extending a singleton would no longer make it a singleton pattern.

Related

Java: why a constructor has access modifier?

For example a class:
//class1
class A {
private A() { } // why would I make it private?
public A(int) { } //why isn't it implicitly public?
}
//class2
class B {
public static void main(String[] args) {
//A a = new A();
}
}
A constructor instantiates a class so why it has the access modifier?
Is there a case when we have to declare a constructor private?
A constructor instantiates a class so why it has the access modifier?
The modifier can be used so you control where the object can be constructed.
Is there a case when we have to declare a constructor private?
Say you have a factory method like
class A {
private A(int n) { }
public static A create(int n) {
return new A(n);
}
}
or you have a shared constructor which should be called directly.
class B {
public B(int n) {
this(n, "");
}
public B(String str) {
this(0, str);
}
private B(int n, String str) { }
}
or you have a Singleton
final class Singleton {
Singleton INSTANCE = new Singleton();
private Singleton() { }
}
however I prefer to use an enum which has a private constructor.
enum Singleton {
INSTANCE;
}
or you have a Utility class
final class Utils {
private Utils() { /* don't create one */ }
public static int method(int n) { }
}
however I prefer to use an enum in this case
enum Utils {
/* no instances */;
public static int method(int n) { }
}
Note: if you use a private constructor on a final class you can still create instances using nested classes, or reflection. If you use an enum you can't create an instance as easily/accidentally.
Warning: You can create instances of an enum using Unsafe
Note in enum the constructor has to be private
class BuySell {
BUY(+1), SELL(-1);
private BuySell(int dir) { }
}
You don't have to make it private explicitly as this is the default.
The private modifier when applied to a constructor works in much the same way as when applied to a normal method or even an instance variable. Defining a constructor with the private modifier says that only the native class (as in the class in which the private constructor is defined) is allowed to create an instance of the class, and no other caller is permitted to do so. There are two possible reasons why one would want to use a private constructor – the first is that you don’t want any objects of your class to be created at all, and the second is that you only want objects to be created internally – as in only created in your class.
Uses of private construtor:-
1) Private constructors can be used in the singleton design pattern
2) Private constructors can prevent creation of objects
This might also help Can a constructor in Java be private? the use cases of private constructor
Constructor are not responsible for Creating a object of a Class, these constructor are only responsible for initialize the member variables only.
There are various Reason behind this. One of the most popular reason behind this is design-Pattern.
//class1
class A {
private A() { } // why would I make it private?
}
why make private Constructor ?
If you want to make a Class singleton then your constructor must be private. then only it is possible to make a Class a Singleton.

create a singleton class in java using public constructor

Do I have to use private constructor to make a class singleton? Is there any other way than using private constructor?
Can't I make a class singleton using public constructor?
If your class has a public constructor, then anybody can create an instance of it at any time. So it's not a singleton any more. For a singleton, there can exist only one instance.
The reason it has to be a private constructor is because you want to prevent people from using it freely to create more than one instance.
A public constructor is possible only if you are able to detect an instance already exist and forbid a another instance being created.
Is there no way other than using private constructor ? Can't we make a class singleton using public constructor ?
Yes, it is actually possible, for example:
class Singleton
{
private static Singleton instance = null;
public Singleton() throws Exception //Singleton with public constructor
{
if(instance != null)
throw new Exception("Instance already exist");
//Else, do whatever..such as creating an instance
}
}
If you really must use public constructor, then you should check whether instance is null and throw an exception.
if(instance != null)
One way to create Singleton object using public constructor with throw exception from constructor if object is already exist.
For Example:
public class Singleton {
private static Singleton singleton;
private String hello;
public Singleton() throws Exception {
if (singleton != null) {
throw new Exception("Object already exist");
}
}
public static Singleton getInstance() throws Exception {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
public static void main(String[] args) {
try {
Singleton single1 = Singleton.getInstance();
single1.setHello("Hello");
System.out.println(single1.getHello());
Singleton single2 = Singleton.getInstance();
System.out.println(single2.getHello());
Singleton single3 = new Singleton();
System.out.println(single3.getHello());
} catch (Exception ex) {
}
}
}
Generally, Singleton pattern is used when you should have exactly 1 object of a class (e.g. Factories are very often implemented as Singletons).
public modifier allows anyone to access your method (as well as your constructor). In that case, anyone can create an instance of your class, thus it won't be a singleton anymore.
By setting private modifier to your constructor, you are sure, it cannot be used outside of the class - no one will create any more objects of that class.
public class SingletonExample {
private static final SingletonExample instance;
// Initialize instance object in static block - done while loading the class by class loader
static {
instance = new SingletonExample();
}
private SingletonExample(){}
public static SingletonExample getInstance(){
return instance;
}
// Method used to create java.test.DateFormat using Oracle SQL Date pattern
public DateFormat createDateFormat(String mask){
if("DD-MM-YYYY HH24:MI:SS".equals(mask)){
return new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
} else if("DD-MM-YYYY".equals(mask)){
return new SimpleDateFormat("dd-MM-yyyy");
} else {
throw new UnsupportedOperationException("Unsupported mask - " + mask);
}
}
}
And usage example
public class SingletonExampleTest{
public static void main(String... args){
java.util.Date date = Calendar.getInstance().getTime();
SingletonExample singleton = SingletonExample.getInstance();
String mask = "DD-MM-YYYY";
DateFormat df = singleton.createDateFormat(mask);
System.out.println(df.format(date));
}
}
The private constructor is a reason, why your class is Singleton.
This Example shows pretty well, how you can use your Singleton class by using getInstance()

Conflicting understanding on singleton implementations

From my understanding a Singleton is a single instance of a class that lasts throughout the span of an applications lifetime. However I've seen a few different implementations of the systems, but I'm always informed that they're wrong, flawed, etc. etc. I'm going to post the two that I see more commonly and I would like to hear opinions/fact based on which implementation is better and why. Implementations are compilable.
Implementation A:
public class Foo {
private static Foo singelton;
private Foo() {
System.out.println("Bar");
}
public static Foo getSingleton() {
if(singleton == null) singleton = new Foo();
return singleton;
}
public static void main(String[] args) {
Foo.getSingleton();
}
}
Implementation B:
public class Foo {
private static final Foo singelton = new Foo();
private Foo() {
if(singelton != null) {
throw new IllegalStateException("Singleton class was already constructed.");
}
System.out.println("Bar");
}
public static void main(String[] args) {
// NOT REQUIRED
}
}
You'll notice in Implementation B that the Singleton instance is final. Also, because of the static implementation the main(String[]) method never needs to construct an instance of this class.
Both Implementation A and B will yield the same results.
Opinions?
Hey you have shown two implementations, the second one is called early initialization and first one is called lazy initialization, as it is initializing the class on demand only.
However your first initialization will fail in multi-threaded environment.
You have to use double checked locking to secure your code.
E. g. :
public class EagerSingleton {
private static volatile EagerSingleton instance = null;
// private constructor
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
if (instance == null) {
synchronized (EagerSingleton.class) {
// Double check
if (instance == null) {
instance = new EagerSingleton();
}
}
}
return instance;
}
}
For morer details please check :
http://howtodoinjava.com/2012/10/22/singleton-design-pattern-in-java/

Creating java singleton with static inner class

I want to use the following pattern to create a singleton in java
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;
}
}
But what happens when the private constructor I want to call is
private Singleton(Object stuff) {... }
How do I pass stuff to INSTANCE = new Singleton()? As in INSTANCE = new Singleton(stuff);
Rewriting the above snippet:
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton(Object stuff) { ... }
/**
* 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(Object stuff) {
return SingletonHolder.INSTANCE;//where is my stuff passed in?
}
}
EDIT:
for those of you claiming this pattern is not thread safe, read here: http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh.
The object I am passing in is the android application context.
If you really want a singleton, there should be only one instance of it (duh!). If you add a parameter to getInstance you probably expect the returned instance to be different (otherwise there is no need for a parameter) which defeats the purpose.
If your goal is to add some configuration when the only instance is created, the simplest way would be to have your singleton query for the configuration information when it is instantiated:
public static final Singleton INSTANCE = new Singleton(getConfiguration());
where getConfiguration returns what is needed (whether by reading a file or forwarding some other variable for example).
Usual disclaimer: Singletons are evil.
Additional resource: Google guide to writing testable code (in case you were not convinced the first time).
You might want to read
a singleton with parameters is not a singleton
The first answer argues why a >>singleton with parameters<< is not a singleton, and doesn't come near a singleton.
public class Singleton {
private static Singleton singleton;
// Private constructor prevents instantiation from other classes
private Singleton() { }
public void addStuff(Object stuff){}
public static Singleton getInstance() {
if(singleton == null) singleton = new Singleton()
return singleton;
}
}
and use it as:
Singleton s = Singleton.getInstance();
s.addStuff(stuff);
or an alternative
public class Singleton {
private static Singleton singleton;
// Private constructor prevents instantiation from other classes
private Singleton() { }
public static void redefine(Object stuff){
singleton = new Singleton(stuff) // choose constructor based on parameters
}
public static Singleton getInstance() {
return singleton;
}
}
Why not get rid of SingletonHolder use factory pattern. You will have to decide what to do, when try to call getInstance twice, but with different 'stuff'.
public class Singleton {
private static Singleton singleton
private final Object stuff;
private Singleton(Object stuff) {
this.stuff = stuff;
}
public static synchronized Singleton getInstance(Object stuff) {
if (singleton == null) {
singleton = new Singleton(stuff);
return singleton;
}
return singleton; // or throw error because trying to re-init
}
}

How can I access a private constructor of a class?

I am a Java developer. In an interview I was asked a question about private constructors:
Can you access a private constructor of a class and instantiate it?
I answered 'No' but was wrong.
Can you explain why I was wrong and give an example of instantiating an object with a private constructor?
One way to bypass the restriction is to use reflections:
import java.lang.reflect.Constructor;
public class Example {
public static void main(final String[] args) throws Exception {
Constructor<Foo> constructor = Foo.class.getDeclaredConstructor();
constructor.setAccessible(true);
Foo foo = constructor.newInstance();
System.out.println(foo);
}
}
class Foo {
private Foo() {
// private!
}
#Override
public String toString() {
return "I'm a Foo and I'm alright!";
}
}
You can access it within the class itself (e.g. in a public static factory method)
If it's a nested class, you can access it from the enclosing class
Subject to appropriate permissions, you can access it with reflection
It's not really clear if any of these apply though - can you give more information?
This can be achieved using reflection.
Consider for a class Test, with a private constructor:
Constructor<?> constructor = Test.class.getDeclaredConstructor(Context.class, String[].class);
Assert.assertTrue(Modifier.isPrivate(constructor.getModifiers()));
constructor.setAccessible(true);
Object instance = constructor.newInstance(context, (Object)new String[0]);
The very first question that is asked regarding Private Constructors in Interviews is,
Can we have Private constructor in a Class?
And sometimes the answer given by the candidate is, No we cannot have private constructors.
So I would like to say, Yes you can have private Constructors in a class.
It is no special thing, try to think it this way,
Private: anything private can be accessed from within the class only.
Constructor: a method which has same name as that of class and it is implicitly called when object of the class is created.
or you can say, to create an object you need to call its constructor, if constructor is not called then object cannot be instantiated.
It means, if we have a private constructor in a class then its objects can be instantiated within the class only. So in simpler words you can say, if the constructor is private then you will not be able to create its objects outside the class.
What's the benefit
This concept can be implemented to achieve singleton object (it means only one object of the class can be created).
See the following code,
class MyClass{
private static MyClass obj = new MyClass();
private MyClass(){
}
public static MyClass getObject(){
return obj;
}
}
class Main{
public static void main(String args[]){
MyClass o = MyClass.getObject();
//The above statement will return you the one and only object of MyClass
//MyClass o = new MyClass();
//Above statement (if compiled) will throw an error that you cannot access the constructor.
}
}
Now the tricky part, why you were wrong, as already explained in other answers, you can bypass the restriction using Reflection.
I like the answers above, but there are two more nifty ways of creating a new instance of a class which has private constructor. It all depends on what you want to achieve and under what circumstances.
1: Using Java instrumentation and ASM
Well in this case you have to start the JVM with a transformer. To do this you have to implement a new Java agent and then make this transformer change the constructor for you.
First create the class transformer. This class has a method called transform. Override this method and inside this method you can use the ASM class reader and other classes to manipulate the visibility of your constructor. After the transformer is done, your client code will have access to the constructor.
You can read more about this here: Changing a private Java constructor with ASM
2: Rewrite the constructor code
Well, this is not really accessing the constructor, but still you can create an instance. Let's assume that you use a third-party library (let's say Guava) and you have access to the code but you don't want to change that code in the jar which is loaded by the JVM for some reason (I know, this is not very lifelike but let's suppose the code is in a shared container like Jetty and you can't change the shared code, but you have separate class loading context) then you can make a copy of the 3rd party code with the private constructor, change the private constructor to protected or public in your code and then put your class at the beginning of the classpath. From that point your client can use the modified constructor and create instances.
This latter change is called a link seam, which is a kind of seam where the enabling point is the classpath.
Using java Reflection as follows :
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Test
{
private Test() //private constructor
{
}
}
public class Sample{
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException
{
Class c=Class.forName("Test"); //specify class name in quotes
//----Accessing private constructor
Constructor con=c.getDeclaredConstructor();
con.setAccessible(true);
Object obj=con.newInstance();
}
}
Yes you could, as mentioned by #Jon Steet.
Another way of accessing a private constructor is by creating a public static method within this class and have its return type as its object.
public class ClassToAccess
{
public static void main(String[] args)
{
{
ClassWithPrivateConstructor obj = ClassWithPrivateConstructor.getObj();
obj.printsomething();
}
}
}
class ClassWithPrivateConstructor
{
private ClassWithPrivateConstructor()
{
}
public void printsomething()
{
System.out.println("HelloWorld");
}
public static ClassWithPrivateConstructor getObj()
{
return new ClassWithPrivateConstructor();
}
}
You can of course access the private constructor from other methods or constructors in the same class and its inner classes. Using reflection, you can also use the private constructor elsewhere, provided that the SecurityManager is not preventing you from doing so.
Yes, we can access the private constructor or instantiate a class with private constructor. The java reflection API and the singleton design pattern has heavily utilized concept to access to private constructor.
Also, spring framework containers can access the private constructor of beans and this framework has used java reflection API.
The following code demonstrate the way of accessing the private constructor.
class Demo{
private Demo(){
System.out.println("private constructor invocation");
}
}
class Main{
public static void main(String[] args){
try{
Class class = Class.forName("Demo");
Constructor<?> con = string.getDeclaredConstructor();
con.setAccessible(true);
con.newInstance(null);
}catch(Exception e){}
}
}
output:
private constructor invocation
I hope you got it.
I hope This Example may help you :
package MyPackage;
import java.lang.reflect.Constructor;
/**
* #author Niravdas
*/
class ClassWithPrivateConstructor {
private ClassWithPrivateConstructor() {
System.out.println("private Constructor Called");
}
}
public class InvokePrivateConstructor
{
public static void main(String[] args) {
try
{
Class ref = Class.forName("MyPackage.ClassWithPrivateConstructor");
Constructor<?> con = ref.getDeclaredConstructor();
con.setAccessible(true);
ClassWithPrivateConstructor obj = (ClassWithPrivateConstructor) con.newInstance(null);
}catch(Exception e){
e.printStackTrace();
}
}
}
Output:
private Constructor Called
Reflection is an API in java which we can use to invoke methods at runtime irrespective of access specifier used with them.
To access a private constructor of a class:
My utility class
public final class Example{
private Example(){
throw new UnsupportedOperationException("It is a utility call");
}
public static int twice(int i)
{
int val = i*2;
return val;
}
}
My Test class which creates an object of the Utility class(Example)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
class Test{
public static void main(String[] args) throws Exception {
int i =2;
final Constructor<?>[] constructors = Example.class.getDeclaredConstructors();
constructors[0].setAccessible(true);
constructors[0].newInstance();
}
}
When calling the constructor it will give the error
java.lang.UnsupportedOperationException: It is a utility call
But remember using reflection api cause overhead issues
Look at Singleton pattern. It uses private constructor.
Yes you can instantiate an instance with a private constructor using Reflection, see the example I pasted below taken from java2s to understand how:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Deny {
private Deny() {
System.out.format("Deny constructor%n");
}
}
public class ConstructorTroubleAccess {
public static void main(String... args) {
try {
Constructor c = Deny.class.getDeclaredConstructor();
// c.setAccessible(true); // solution
c.newInstance();
// production code should handle these exceptions more gracefully
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
The basic premise for having a private constructor is that having a private constructor restricts the access of code other than own class' code from making objects of that class.
Yes we can have private constructors in a class and yes they can be made accessible by making some static methods which in turn create the new object for the class.
Class A{
private A(){
}
private static createObj(){
return new A();
}
Class B{
public static void main(String[]args){
A a=A.createObj();
}}
So to make an object of this class, the other class has to use the static methods.
What is the point of having a static method when we are making the constructor private?
Static methods are there so that in case there is a need to make the instance of that class then there can be some predefined checks that can be applied in the static methods before creation of the instance. For example in a Singleton class, the static method checks if the instance has already been created or not. If the instance is already created then it just simply returns that instance rather than creating a new one.
public static MySingleTon getInstance(){
if(myObj == null){
myObj = new MySingleTon();
}
return myObj;
}
We can not access private constructor outside the class but using Java Reflection API we can access private constructor. Please find below code:
public class Test{
private Test()
System.out.println("Private Constructor called");
}
}
public class PrivateConsTest{
public void accessPrivateCons(Test test){
Field[] fields = test.getClass().getDeclaredFields();
for (Field field : fields) {
if (Modifier.isPrivate(field.getModifiers())) {
field.setAccessible(true);
System.out.println(field.getName()+" : "+field.get(test));
}
}
}
}
If you are using Spring IoC, Spring container also creates and injects object of the class having private constructor.
I tried like this it is working. Give me some suggestion if i am wrong.
import java.lang.reflect.Constructor;
class TestCon {
private TestCon() {
System.out.println("default constructor....");
}
public void testMethod() {
System.out.println("method executed.");
}
}
class TestPrivateConstructor {
public static void main(String[] args) {
try {
Class testConClass = TestCon.class;
System.out.println(testConClass.getSimpleName());
Constructor[] constructors = testConClass.getDeclaredConstructors();
constructors[0].setAccessible(true);
TestCon testObj = (TestCon) constructors[0].newInstance();
//we can call method also..
testObj.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Simple answer is yes we can have private constructors in Java.
There are various scenarios where we can use private constructors. The major ones are
Internal Constructor chaining
Singleton class design pattern
Also have another option create the getInstance() where we can create instance of private constructor inside same class and return that object.
class SampleClass1{
private SampleClass1() {
System.out.println("sample class constructor");
}
public static SampleClass1 getInstance() {
SampleClass1 sc1 = new SampleClass1();
return sc1;
}
}
public class SingletonDemo {
public static void main(String[] args) {
SampleClass1 obj1 = SampleClass1.getInstance();
}
}
We can create instance of private class by creating createInstance() in the same class and simply call the same method by using class name in main():
class SampleClass1{
private SampleClass1() {
System.out.println("sampleclass cons");
}
public static void createInstance() {
SampleClass1 sc = new SampleClass1();
}
}
public class SingletonDemo {
public static void main(String[] args) {
//SampleClass1 sc1 = new SampleClass1();
SampleClass1.createInstance();
}
}
Well, you can also if there are any other public constructors. Just because the parameterless constructor is private doesn't mean you just can't instantiate the class.
you can access it outside of the class its very easy to access
just take an example of singaltan class we all does the same thing make the private constructor and access the instance by static method here is the code associated to your query
ClassWithPrivateConstructor.getObj().printsomething();
it will definately work because i have already tested

Categories