Monday, January 21, 2019

Invoke Method at Runtime Using Java Reflection API

In this post we’ll see how to invoke a method at runtime using Java reflection API. You can even call a private method using reflection.

How to get the method instance

In order to invoke a method first thing you need to do is to get the instance of the method. Once you have the class object (instance of the class in which method is defined) you can use one of the following methods to get an instance of a single method or get all the methods of the class in an array.

  • getMethod(String name, Class<?>... parameterTypes)- Using getMethod() you can get a Method object for the specified public member method of the class (instance or static). As method arguments pass the method name and the type of the method parameters.
  • getMethods()- This method returns an array containing Method objects for all the public methods of the class even the inherited ones.
  • getDeclaredMethod(String name, Class<?>... parameterTypes)- Using getDeclaredMethod() you can get a Method object for the specified method of the class (having any access modifier public, private, protected, default).
  • getDeclaredMethods()- This method returns an array containing Method objects for all the declared methods of the class including public, protected, default (package) access, and private methods, but excluding inherited methods.

How to invoke method using Java reflection API

Once you have a method instance using any of the above mentioned methods you can invoke that method by calling java.lang.reflect.Method.invoke().

First argument to the invoke method is the object instance on which this particular method is to be invoked i.e. object of the class where the method resides. If the method called is static, first argument should be null. Subsequent arguments are the method's parameters.

In case underlying method throws an exception, it will be wrapped by an java.lang.reflect.InvocationTargetException.

Invoking class methods using Java reflection API example

As a preparation for the example code let’s have a class called TestClass.java with methods that are invoked using Java reflection API.

public class TestClass {
 public String appendString(String str1, String str2) {
  return str1+ " " +str2;
 }
 
 static int addValues(int a, int b){
  return a+b;
 }
 
 private boolean compare(int a, int b){
  return a > b;
 }
}

Invoking instance method using Java reflection API example

If you have to invoke the public method appendString() of the given class then it can be done using the following code-

public void callMethod(){
  Class<?> c = null;
  String result="";
  try {
    // Getting Class instance
    c = Class.forName("org.netjs.prog.TestClass");
  } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  // Getting class object
  TestClass obj = new TestClass();        
  Method method = null;
  try {
    // getting method instance by passing method name and parameter types
    method = c.getDeclaredMethod("appendString", String.class, String.class);
  } catch (NoSuchMethodException | SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  try {
    // invoking method
    result = (String)method.invoke(obj, "Hello", "World");
  } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  System.out.println("Returned result is- " + result);    
}

Output

Returned result is- Hello World

Invoking static method of a class

If you have to invoke a static method of a class then while calling the invoke method pass the first argument (which denotes the class object) as null.

public void callMethod(){
  Class<?> c = null;
  int result = 0;
  try {
    // Getting Class instance
    c = Class.forName("org.netjs.prog.TestClass");
  } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }        
  Method method = null;
  try {
    // getting method instance by passing method name and parameter types
    method = c.getDeclaredMethod("addValues", int.class, int.class);
  } catch (NoSuchMethodException | SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  try {
    // invoking static method of the class
    result = (Integer)method.invoke(null, 20, 30);
  } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  System.out.println("Returned result is- " + result);    
}

Output

Returned result is- 50

Invoking private method using Java reflection API

You can even invoke the private method of the class using reflection in Java.

Using getDeclaredMethod() you can get the private method of the class. Once you have the method object you can use the setAccessible() method which is inherited from class java.lang.reflect.AccessibleObject to set the access for the private method as true at run time and then invoke it from another class.

public void callMethod(){
  Class<?> c = null;
  boolean result = false;
  try {
    // Getting Class instance
    c = Class.forName("org.netjs.prog.TestClass");
  } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }    
  // Getting class object
  TestClass obj = new TestClass();    
  Method method = null;
  try {
    // getting method instance by passing method name and parameter types
    method = c.getDeclaredMethod("compare", int.class, int.class);
    // Making method accessible
    method.setAccessible(true);
  } catch (NoSuchMethodException | SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  try {
    // invoking private method of the class
    result = (Boolean)method.invoke(obj, 60, 30);
  } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  System.out.println("Returned result is- " + result);    
}

Output

Returned result is- true

That's all for this topic Invoke Method at Runtime Using Java Reflection API. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Generating getters and setters using Reflection - Java Program
  2. Reflection in Java - Array
  3. Zipping Files And Folders in Java
  4. How to Run Threads in Sequence - Java Program
  5. Core Java Basics Interview Questions

You may also like-

  1. Externalizable interface in Java
  2. Garbage Collection in Java
  3. Spliterator in Java
  4. AtomicInteger in Java Concurrency
  5. Inheritance in Java
  6. static Import in Java
  7. Try-With-Resources in Java With Examples
  8. Spring Email Scheduling Example Using Quartz Scheduler