Call Methods at Runtime Using Java Reflection

1. Overview

In this short article, we’ll take a quick look at how to invoke methods at runtime using the Java Reflection API.

2. Getting Ready

Let’s create a simple class which we’ll use for the examples that follow:

public class Operations {
    public double publicSum(int a, double b) {
        return a + b;
    }

    public static double publicStaticMultiply(float a, long b) {
        return a * b;
    }

    private boolean privateAnd(boolean a, boolean b) {
        return a && b;
    }

    protected int protectedMax(int a, int b) {
        return a > b ? a : b;
    }
}

3. Obtaining a Method Object

First, we need to get a Method object that reflects the method we want to invoke. The Class object, representing the type in which the method is defined, provides two ways of doing this.

3.1. getMethod()

We can use getMethod() to find any public method, be it static or instance that is defined in the class or any of its superclasses.

It receives the method name as the first argument, followed by the types of the method’s arguments:

Method sumInstanceMethod
  = Operations.class.getMethod("publicSum", int.class, double.class);

Method multiplyStaticMethod
  = Operations.class.getMethod(
    "publicStaticMultiply", float.class, long.class);

3.2. getDeclaredMethod()

We can use getDeclaredMethod() to get any method defined in the class. This includes public, protected, default access, and even private methods but excludes inherited ones.

It receives the same parameters as getMethod():

Method andPrivateMethod
  = Operations.class.getDeclaredMethod(
    "privateAnd", boolean.class, boolean.class);
Method maxProtectedMethod
  = Operations.class.getDeclaredMethod("protectedMax", int.class, int.class);

4. Invoking Methods

With the Method instance in place, we can now call invoke() to execute the underlying method and get the returned object.

4.1. Instance Methods

To invoke an instance method, the first argument to invoke() must be an instance of Method that reflects the method being invoked:

@Test
public void givenObject_whenInvokePublicMethod_thenCorrect() {
    Method sumInstanceMethod
      = Operations.class.getMethod("publicSum", int.class, double.class);

    Operations operationsInstance = new Operations();
    Double result
      = (Double) sumInstanceMethod.invoke(operationsInstance, 1, 3);

    assertThat(result, equalTo(4.0));
}

4.2. Static Methods

Since these methods don’t require an instance to be called, we can pass null as the first argument:

@Test
public void givenObject_whenInvokeStaticMethod_thenCorrect() {
    Method multiplyStaticMethod
      = Operations.class.getDeclaredMethod(
        "publicStaticMultiply", float.class, long.class);

    Double result
      = (Double) multiplyStaticMethod.invoke(null, 3.5f, 2);

    assertThat(result, equalTo(7.0));
}

5. Method Accessibility

By default, not all reflected methods are accessible. This means that the JVM enforces access control checks when invoking them.

For instance, if we try to call a private method outside its defining class or a protected method from outside a subclass or its class’ package, we’ll get an IllegalAccessException:

@Test(expected = IllegalAccessException.class)
public void givenObject_whenInvokePrivateMethod_thenFail() {
    Method andPrivateMethod
      = Operations.class.getDeclaredMethod(
        "privateAnd", boolean.class, boolean.class);

    Operations operationsInstance = new Operations();
    Boolean result
      = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false);

    assertFalse(result);
}

@Test(expected = IllegalAccessException.class)
public void givenObject_whenInvokeProtectedMethod_thenFail() {
    Method maxProtectedMethod
      = Operations.class.getDeclaredMethod(
        "protectedMax", int.class, int.class);

    Operations operationsInstance = new Operations();
    Integer result
      = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4);
    
    assertThat(result, equalTo(4));
}

By calling setAccesible(true) on a reflected method object, the JVM suppresses the access control checks and allows us to invoke the method without throwing an exception:

@Test
public void givenObject_whenInvokePrivateMethod_thenCorrect() {
    // ...
    andPrivateMethod.setAccessible(true);
    // ...
    Boolean result
      = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false);

    assertFalse(result);
}

@Test
public void givenObject_whenInvokeProtectedMethod_thenCorrect() {
    // ...
    maxProtectedMethod.setAccessible(true);
    // ...
    Integer result
      = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4);

    assertThat(result, equalTo(4));
}

6. Conclusion

In this quick article, we’ve seen how to call instance and static methods of a class at runtime through reflection. We also showed how to change the accessible flag on the reflected method objects to suppress Java access control checks when invoking private and protected methods.

As always, the example code can be found over on Github.

Related posts:

Java Program to Check Whether a Given Point is in a Given Polygon
Java Program to Implement Pagoda
Jackson – Marshall String to JsonNode
Quick Guide to Spring MVC with Velocity
Java Program to Check Whether Graph is DAG
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
Tìm hiểu về xác thực và phân quyền trong ứng dụng
Java Program to Implement Knapsack Algorithm
The Modulo Operator in Java
Object Type Casting in Java
How to Set TLS Version in Apache HttpClient
Using Custom Banners in Spring Boot
Java Program to Implement Gift Wrapping Algorithm in Two Dimensions
Java Program to Apply DFS to Perform the Topological Sorting of a Directed Acyclic Graph
Serverless Functions with Spring Cloud Function
Spring Boot - Eureka Server
Java Program to Implement Interpolation Search Algorithm
Hướng dẫn Java Design Pattern – Mediator
How to Convert List to Map in Java
Java Program to Implement Jarvis Algorithm
Java Program to Generate Randomized Sequence of Given Range of Numbers
@DynamicUpdate with Spring Data JPA
Java Program to Use rand and srand Functions
Java Program to Implement Quick Hull Algorithm to Find Convex Hull
Java Program to Permute All Letters of an Input String
A Guide to the finalize Method in Java
Java Program to Solve Set Cover Problem assuming at max 2 Elements in a Subset
Setting a Request Timeout for a Spring REST API
Pagination and Sorting using Spring Data JPA
Removing all Nulls from a List in Java
Java Program to Implement Find all Back Edges in a Graph
Java Program to Implement Park-Miller Random Number Generation Algorithm