Similar to
reflection API for methods, there is also reflection API to get information about the
constructors of a class.
Using java.lang.reflect.Constructor
class in Java reflection API you can get information about the modifiers, parameters, annotations, and thrown exceptions.
You can also create a new instance of a class using a specified constructor.
How to get Constructor object using reflection
As always the starting point is the Class and there are four methods provided by the class Class
for getting the constructors.
- getConstructor(Class<?>... parameterTypes)- Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
- getConstructors()- Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.
- getDeclaredConstructor(Class<?>... parameterTypes)– Returns a Constructor object that reflects the specified constructor of the class or interface represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
- getDeclaredConstructors()- Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors.
Getting constructor information using reflection Java example
For example we’ll be using this class TestClass which has one public constructor with 2 args and a private constructor.
TestClass.java
public class TestClass { private int value; private String name; // public Constructor public TestClass(int value, String name) { this.value = value; } // private constructor private TestClass() { } public void showValue() { System.out.println("Value - " + value); } }
If you want to get constructors using the above 4 methods it can be done as follows–
import java.lang.reflect.Constructor; import java.util.Arrays; public class ReflectConstructor { public static void main(String[] args) { try { Class<?> c = Class.forName("org.prgm.TestClass"); // To get constructor with 2 args Constructor<?> constructor = c.getConstructor(int.class, String.class); //Constructor<?> constructor = c.getConstructor(new Class[]{int.class, String.class}); System.out.println("constructor " + constructor.toString()); // to get private constructor using getDeclaredConstructor() method constructor = c.getDeclaredConstructor(); System.out.println("constructor " + constructor.toString()); // Getting constructors of the class Constructor<?>[] constructors = c.getConstructors(); System.out.println("Constructors - " + Arrays.toString(constructors)); Constructor<?>[] Decconstructors = c.getDeclaredConstructors(); System.out.println("Declared constructors - " + Arrays.toString(Decconstructors)); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Output
constructor public org.prgm.TestClass(int,java.lang.String) constructor private org.prgm.TestClass() Constructors - [public org.prgm.TestClass(int,java.lang.String)] Declared constructors - [public org.prgm.TestClass(int,java.lang.String), private org.prgm.TestClass()]
Here note that in the first call two parameters are passed with the getConstructor() method which match the arguments of the constructor in the TestClass class. Since parameter is defined as varargs in getConstructor() so you can pass as comma separated parameters or as an array of class objects. Which is done as an illustration in the commented code.
Second call uses the getDeclaredConstructor(); method as that can return constructor object pertaining to private constructor too.
Same way getDeclaredConstructors() method returns an array of Constructor objects reflecting all the constructors of the class public or private where as getConstructors() method returns an array of constructor objects reflecting all the public constructors of the class.
Class<?> c = Class.forName("org.prgm.TestClass"); Constructor<?>[] Decconstructors = c.getDeclaredConstructors(); for(Constructor<?> ctr : Decconstructors){ System.out.println("Constructor -- " + ctr.getName()); Class<?>[] pType = ctr.getParameterTypes(); for (int i = 0; i < pType.length; i++) { System.out.println("Parameter -- " + pType[i]); } }
Getting modifiers of the constructors using reflection
You can get modifiers of the constructors of the class through reflection using getModifiers() method.
Class<?> c = Class.forName("org.prgm.TestClass"); Constructor<?>[] Decconstructors = c.getDeclaredConstructors(); for(Constructor<?> ctr : Decconstructors){ System.out.println("Constructor -- " + ctr.getName() + " has modifier " + Modifier.toString(ctr.getModifiers())); }
Output
Constructor -- org.prgm.TestClass has modifier public Constructor -- org.prgm.TestClass has modifier private
Creating class instance using reflection
In reflection API there are two methods for creating instances of classes- java.lang.reflect.Constructor.newInstance()
and
Class.newInstance()
. It is preferable to go with the one provided by the Constructor class for the reasons explained here-
Class.newInstance()
can only invoke the zero-argument constructor, whileConstructor.newInstance()
may invoke any constructor, regardless of the number of parameters.- Class.newInstance() requires that the constructor be visible;
Constructor.newInstance() can invoke private constructors also by setting accessibility to true. - Class.newInstance() throws any exception thrown by the constructor whether it is
checked or unchecked exception.
Constructor.newInstance() always wraps the thrown exception with an InvocationTargetException.
For the TestClass.java which has one public constructor with two arguments and one no-arg private constructor, creating new class instances can be done as follows.
Class<?> c = Class.forName("org.prgm.TestClass"); Constructor<?>[] Decconstructors = c.getDeclaredConstructors(); for(Constructor<?> ctr : Decconstructors){ System.out.println("Constructor -- " + ctr.getName()); try { TestClass t; if(Modifier.toString(ctr.getModifiers()).equals("private")){ // Setting accessibility to true if it's a private constructor ctr.setAccessible(true); t = (TestClass)ctr.newInstance(); }else{ t = (TestClass)ctr.newInstance(100, "InstanceTest"); } t.showValue(); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } }
Output
Constructor -- org.prgm.TestClass Value - 100 Constructor -- org.prgm.TestClass Value – 0
In the code there is a check for the modifier of the constructor. If it is private then the set the accessible flag to true, with that even private constructor can be accessed from another class and an instance created.
That's all for this topic Reflection in Java - Getting Constructor Information. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Advanced Tutorial Page
Related Topics
You may also like-