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)