August 1, 2022

Java Reflection – Class Methods

Using Java Reflection API you can get information about the methods of the class and even invoke methods at run time. In Java Reflection API there is a class java.lang.reflect.Method that has methods for accessing field's type, field’s modifier and setting and getting values of a field.

Getting Method instance

First thing is to get the instance of Method 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.

  • getMethod(String name, Class<?>... parameterTypes)- This method returns a Method object for the specified public member method name of the class or interface
  • getMethods()- Returns an array containing Method objects reflecting all the public methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.
  • getDeclaredMethod(String name, Class<?>... parameterTypes)- Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object.
  • getDeclaredMethods()- Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods.
  • getEnclosingMethod()- If this Class object represents a local or anonymous class within a method, this method returns a Method object which represents the immediately enclosing method of the underlying class.

Getting information about class methods – Java example

This example shows how you can use Java Reflection API to get Method object and using that get information about method type and its modifiers. Methods of java.lang.reflect.Method class that are used in the example are-

  • getName()- Returns the name of the method represented by this Method object, as a String.
  • getParameters()- Returns an array of Parameter objects that represent all the parameters of the method.
  • getParameterTypes()- Returns an array of Class objects represent the parameter types of the method.
  • getReturnType()- Returns a Class object that represents the formal return type of the method represented by this Method object.
  • getModifiers()- Returns the method modifiers.

For the example we’ll use the following class structure.

There is an interface Operation.java

public interface Operation {
	void sum(int a, int b);
}

One Java class that acts as a super class.

public class Message {
  String msg;
  Message(String msg){
    this.msg = msg;
  }
  public void displayMessage(){
    System.out.println(msg);
  }
}

Another class that implements Operation interface and extends Message.java

public class Child extends Message implements Operation {	
  Child(String msg) {
    super(msg);
  }

  @Override
  public void sum(int a, int b) {
    System.out.println("Sum is- " + a+b);
  }

  private String prepareMessage(String msg) {
    return "Hello " + msg;
  }
}
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Child child = new Child("Java Reflection example");
      // get instance of Class
      Class<?> c = child.getClass();
        
      System.out.println("--- Using getMethod(methodName, parameters) ---");
      Method method = c.getMethod("sum", int.class, int.class);
      System.out.println("Method Name- " + method.getName());
      System.out.println("Method params- " + Arrays.toString(method.getParameters()));
      System.out.println("Method param types- " + Arrays.toString(method.getParameterTypes()));
      System.out.println("Method Returns- " + method.getReturnType());
      int mod = method.getModifiers();
      System.out.println("Method modifiers - " + Modifier.toString(mod));
      
      System.out.println("--- Using getDeclaredMethod(methodName, parameters) ---");
      System.out.println("Method Name- " + method.getName());
      method = c.getDeclaredMethod("prepareMessage", String.class);
      System.out.println("Method params- " + Arrays.toString(method.getParameters()));
      
      System.out.println("--- Using getMethods() ---");
      Method[] methods = c.getMethods();
      System.out.println("All Methods " + Arrays.toString(methods));
      
      System.out.println("--- Using getDeclaredMethods() ---");       
      methods = c.getDeclaredMethods();
        for(Method m: methods) {
          System.out.println("Method Name- " + m.getName());
          System.out.println("Method Parameters- " + Arrays.toString(m.getParameters()));
        }
        
    } catch (NoSuchMethodException | SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
--- Using getMethod(methodName, parameters) ---
Method Name- sum
Method params- [int arg0, int arg1]
Method param types- [int, int]
Method Returns- void
Method modifiers - public
--- Using getDeclaredMethod(methodName, parameters) ---
Method Name- sum
Method params- [java.lang.String arg0]
--- Using getMethods() ---
All Methods [public void com.knpcode.programs.Child.sum(int,int), public void com.knpcode.programs.Message.displayMessage(), public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
--- Using getDeclaredMethods() ---
Method Name- sum
Method Parameters- [int arg0, int arg1]
Method Name- prepareMessage
Method Parameters- [java.lang.String arg0]

Few things to observe from the example are-

  1. Using getDeclaredMethod() you can also get information about a private method of the class.
  2. GetMethods() returns all the methods of the class and also of the super class.
  3. GetDeclaredMethods() returns all the methods of the class even private and protected.

Invoking class method using Java Reflection

You can invoke method of a class at runtime using Reflection API. In Method class there is invoke(Object obj, Object... args) which is used for the purpose.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Child child = new Child("Java Reflection example");
      // get instance of Class
      Class<?> c = child.getClass();
      Method method = c.getMethod("sum", int.class, int.class);
      // Invoking method
      method.invoke(child, 5, 6);
    } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Invoking private method using Java Reflection

You can even invoke a private method of the class using Java Refelction API.

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

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionDemo {
  public static void main(String[] args) {
    try {
      Child child = new Child("Java Reflection example");
        // get instance of Class
        Class<?> c = child.getClass();
        Method method = c.getDeclaredMethod("prepareMessage", String.class);
        method.setAccessible(true);
        // Invoking method
        String message = (String)method.invoke(child, "Java Reflection API");
        System.out.println("Message- " + message);
    } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Message- Hello Java Reflection API

That's all for the topic Java Reflection – Class Methods. 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