July 29, 2022

Java Reflection – Class Constructors

Using Java Reflection you can get information about the constructors of the class and create a new class instance too. In Java Reflection API there is a class java.lang.reflect.Constructor that has methods for finding constructors, retrieving constructor modifiers and creating new instance.

Getting Constructor instance

First thing is to get the instance of java.lang.reflect.Constructor class for that you will have to use methods of the java.lang.Class as that class is the entry point for all reflection operations. There are 5 methods for getting Constructor instance-

  • getConstructor(Class<?>... parameterTypes)- This method returns a Constructor object where the passed parameter types match the parameters of the constructor in the class.
  • getConstructors()- Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.
  • getDeclaredConstructor(Class<?>... parameterTypes)- This method returns a Constructor object where the passed parameter types match the parameters of the constructor in the class. How this method differs from getCOnstructor() is that this method can also match a private or protected constructor.
  • getDeclaredConstructors()- Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object.
  • getEnclosingConstructor()- If this Class object represents a local or anonymous class within a constructor, returns a Constructor object representing the immediately enclosing constructor of the underlying class.

Getting information about class constructors – Java example

This example shows how to get information like parameter types, modifiers of individual/all constructors of a class.

Following is the class used for the example.

public class Message {
  String msg;
  public Message(String msg){
    this.msg = msg;
  }

  private Message() {
    
  }
  public void displayMessage(){
    System.out.println(msg);
  }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Message message = new Message("Java Reflection example");
      // get instance of Class
      Class<?> c = message.getClass();
      System.out.println("--- getConstructor() ---");
      Constructor<?> constructor = c.getConstructor(new Class[]{String.class});
      System.out.println("Constructor Name- " + constructor.getName());
      System.out.println("Constructor Parameters- " + Arrays.toString(constructor.getParameterTypes()));
      System.out.println("Constructor Modifier- " + Modifier.toString(constructor.getModifiers()));
      
      System.out.println("--- getDeclaredConstructor() ---");
      constructor = c.getDeclaredConstructor();
      System.out.println("Constructor Name- " + constructor.getName());
      System.out.println("Constructor Parameters- " + Arrays.toString(constructor.getParameterTypes()));
      System.out.println("Constructor Modifier- " + Modifier.toString(constructor.getModifiers()));
      
      System.out.println("--- getConstructors() ---");
      Constructor<?>[] cons = c.getConstructors();
      System.out.println("Constructor Name- " + Arrays.toString(cons));
      
      System.out.println("--- getDeclaredConstructors() ---");
      cons = c.getDeclaredConstructors();
      for(Constructor<?> ct : cons) {
        System.out.println("Constructor Name- " + ct.getName());
        System.out.println("Constructor Parameters- " + Arrays.toString(ct.getParameterTypes()));
        System.out.println("Constructor Modifier- " + Modifier.toString(ct.getModifiers()));
      }                       
    } catch (NoSuchMethodException | IllegalArgumentException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
--- getConstructor() ---
Constructor Name- com.knpcode.programs.Message
Constructor Parameters- [class java.lang.String]
Constructor Modifier- public
--- getDeclaredConstructor() ---
Constructor Name- com.knpcode.programs.Message
Constructor Parameters- []
Constructor Modifier- private
--- getConstructors() ---
Constructor Name- [public com.knpcode.programs.Message(java.lang.String)]
--- getDeclaredConstructors() ---
Constructor Name- com.knpcode.programs.Message
Constructor Parameters- [class java.lang.String]
Constructor Modifier- public
Constructor Name- com.knpcode.programs.Message
Constructor Parameters- []
Constructor Modifier- private

Get new class instance using Java Reflection

In Java there are two reflective methods for creating instances of classes: java.lang.reflect.Constructor.newInstance() and Class.newInstance(). Here we’ll see an example of creating class instance using Constructor class of the Java Reflection API, which is also the preferred way as per Java docs- https://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

newInstance(Object... initargs)- Uses the constructor represented by this Constructor object to create and initialize a new instance of the constructor's declaring class, with the specified initialization parameters.

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

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Message message = new Message("Java Reflection example");
      // get instance of Class
      Class<?> c = message.getClass();
      Constructor<?> constructor = c.getConstructor(new Class[]{String.class});
      Message m = (Message)constructor.newInstance("Hello");
      m.displayMessage();              
    } catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Get new class instance using private constructor

You can get a new class instance by using the private constructor of the class too.

Once you have the Constructor object you have to set the access for it as true using the setAccessible() method which is inherited from class java.lang.reflect.AccessibleObject.

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

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Message message = new Message("Java Reflection example");
      // get instance of Class
      Class<?> c = message.getClass();
      // Getting private constructor
      Constructor<?> constructor = c.getDeclaredConstructor();
      constructor.setAccessible(true);
      Message m = (Message)constructor.newInstance();
      m.displayMessage();                   
    } catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

That's all for the topic Java Reflection – Class Constructors. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment