We know that we 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;
}

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

package com.roytuts.constructor.instance;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

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();
		}
	}

}

 The output of the above class after execution:

Class Name: java.lang.System
-------------------------------------------------
sysObject: [email protected]
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: [email protected]
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)

 That’s all. Thanks for reading.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *