Instantiate Object From A Class Which Contains Private constructor

Private Constructor

You probably know that you cannot make any object if the Class contains private constructor but this is not true until a special care is taken to the private constructor. This tutorial shows an example how to create instance using Reflection even if the classes have private constructors. Though if the special care is taken to the private constructor then you will not be able to create an instance.

The below example creates instances from classes java.lang.System and java.lang.Runtime, but you will not be able to create any instance from java.lang.Class because it cheks some security permission and it will throw Security exception.

While accessing Class’s private constructor it throws following exception:

java.lang.SecurityException: Can not make a java.lang.Class constructor accessible
    at java.lang.reflect.AccessibleObject.setAccessible0(AccessibleObject.java:118)
    at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:108)

 
The above exception occurs due to the following snippets from AccessibleObject.java class:

private static void setAccessible0(AccessibleObject obj, boolean flag)
    throws SecurityException
{
    if (obj instanceof Constructor && flag == true) {
        Constructor c = (Constructor)obj;
        if (c.getDeclaringClass() == Class.class) {
        throw new SecurityException("Can not make a java.lang.Class" +
                        " constructor accessible");
        }
    }
    obj.override = flag;
}

Create Instance From Private Constructor

The complete code is given below how to instantiate object from a class which has private constructor.

public class InstantiatePrivateConstructor {

	public static void main(String[] args) {
		String systemClassName = "java.lang.System";
		String runtimeClassName = "java.lang.Runtime";
		String classClassName = "java.lang.Class";

		try {
			Class<?> system = Class.forName(systemClassName);
			Constructor<?> sysConstructor = system.getDeclaredConstructor();
			sysConstructor.setAccessible(true);

			System sysObject = (System) sysConstructor.newInstance();
			Field[] systemFields = sysObject.getClass().getFields();

			System.out.println("Class Name: " + systemClassName);
			System.out.println("-------------------------------------------------");

			System.out.println("sysObject: " + sysObject);
			System.out.println("systemFields length: " + systemFields.length);

			for (int i = 0; i < systemFields.length; i++) {
				System.out.println("Field Name: " + systemFields[i].getName());
				System.out.println("Field Type: " + systemFields[i].getType());
			}

			System.out.println("===================================================");
			System.out.println();

			Class<?> runtime = Class.forName(runtimeClassName);
			Constructor<?> runConstructor = runtime.getDeclaredConstructor();
			runConstructor.setAccessible(true);

			Runtime runObject = (Runtime) runConstructor.newInstance();
			Field[] runFields = runObject.getClass().getFields();

			System.out.println("Class Name: " + runtimeClassName);
			System.out.println("-------------------------------------------------");

			System.out.println("runObject: " + runObject);
			System.out.println("runFields length: " + runFields.length);

			for (int i = 0; i < runFields.length; i++) {
				System.out.println("Field Name: " + runFields[i].getName());
				System.out.println("Field Type: " + runFields[i].getType());
			}

			System.out.println("===================================================");
			System.out.println();

			Class<?> clss = Class.forName(classClassName);
			Constructor<?> classConstructor = clss.getDeclaredConstructor();

			System.out.println("Class Name: " + classClassName);
			System.out.println("-------------------------------------------------");

			System.out.println("Now you will get Exception for below line");
			System.out.println();

			classConstructor.newInstance();
		} catch (InstantiationException | IllegalAccessException | SecurityException | NoSuchMethodException
				| IllegalArgumentException | InvocationTargetException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

Testing Private Constructor

Let’s look at the following output:

Class Name: java.lang.System
-------------------------------------------------
sysObject: java.lang.System@63961c42
systemFields length: 3
Field Name: in
Field Type: class java.io.InputStream
Field Name: out
Field Type: class java.io.PrintStream
Field Name: err
Field Type: class java.io.PrintStream
===================================================

Class Name: java.lang.Runtime
-------------------------------------------------
runObject: java.lang.Runtime@1be6f5c3
runFields length: 0
===================================================

java.lang.NoSuchMethodException: java.lang.Class.<init>()
	at java.base/java.lang.Class.getConstructor0(Class.java:3354)
	at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2558)
	at com.roytuts.constructor.instance.InstantiatePrivateConstructor.main(InstantiatePrivateConstructor.java:58)

Source Code

Download

Leave a Reply

Your email address will not be published.