DevNotes
Support
Reflection · Chapter 08

Methods in Reflection

The Method API — getMethods vs getDeclaredMethods, invoking public, private, static and parameterized methods, return values, overloads, InvocationTargetException and framework usage.

◷ 7 min read§ 14 sections? 8 interview questions{ } 24 code examples

#Introduction

So far Reflection can inspect classes, create objects, and read and modify fields. Now we'll learn how Reflection can inspect and invoke methods dynamically at runtime.

This is one of the most used Reflection features in Spring, JUnit, Hibernate, Jackson, Mockito and Apache CXF. Whenever a framework automatically executes a method without you explicitly calling it, Reflection is usually involved.

#What is a Method?

A method is a behaviour of an object.

Java
class Employee {
    public void work() {
        System.out.println("Working...");
    }

    public int salary() {
        return 50000;
    }
}

Normally:

Java
Employee emp = new Employee();
emp.work();

The compiler knows which class, which object and which method. Reflection removes this dependency.

#The Method Reflection API

Reflection represents every method using java.lang.reflect.Method.

Class
Method
Inspect metadata
Invoke method
Return result

#Getting Methods

Java
public class Employee {
    public void work() {}
    public void display() {}
    private void secret() {}
}

getMethods() — Public, Including Inherited

Java
Class<?> cls = Employee.class;

Method[] methods = cls.getMethods();

for (Method method : methods) {
    System.out.println(method.getName());
}
Output (partial)
work
display
wait
equals
hashCode
toString
notify

Notice: methods inherited from Object are also returned.

getDeclaredMethods() — Declared in This Class Only

Java
Method[] methods = Employee.class.getDeclaredMethods();

for (Method method : methods) {
    System.out.println(method.getName());
}
Output
work
display
secret

Only methods declared inside Employee are returned — including the private one. (The order of returned methods isn't guaranteed.)

getMethods() vs getDeclaredMethods()

MethodPublicPrivateInherited
getMethods()✓✗✓
getDeclaredMethods()✓✓✗

#Getting a Specific Method

Java
class Employee {
    public void work() {
    }
}

Method method = Employee.class.getMethod("work");

A Private Method

Java
class Employee {
    private void secret() {
    }
}

Method method = Employee.class.getDeclaredMethod("secret");
method.setAccessible(true);

Now Reflection can invoke it.

A Parameterized Method

Java
class Employee {
    public void save(String name, int age) {
    }
}

Method method = Employee.class.getMethod("save", String.class, int.class);

Notice: we pass parameter types, not values.

#Invoking Methods

A Simple Method

Java
class Employee {
    public void work() {
        System.out.println("Working");
    }
}

Employee emp = new Employee();

Method method = Employee.class.getMethod("work");
method.invoke(emp);
Output
Working

Reflection executed the method dynamically.

With Parameters

Java
class Employee {
    public void greet(String name) {
        System.out.println("Hello " + name);
    }
}

Employee emp = new Employee();

Method method = Employee.class.getMethod("greet", String.class);
method.invoke(emp, "Rahul");
Output
Hello Rahul

Arguments are supplied at runtime.

Returning a Value

Java
class Employee {
    public int salary() {
        return 50000;
    }
}

Employee emp = new Employee();

Method method = Employee.class.getMethod("salary");
Object result = method.invoke(emp);

System.out.println(result);
Output
50000

Notice: invoke() always returns Object. Primitive return values are automatically boxed (here an Integer), and void methods return null.

A Private Method

Java
class Employee {
    private void secret() {
        System.out.println("Hidden");
    }
}

Employee emp = new Employee();

Method method = Employee.class.getDeclaredMethod("secret");
method.setAccessible(true);
method.invoke(emp);
Output
Hidden

Reflection bypasses access checks (subject to module/security restrictions in modern Java).

A Static Method

Java
class Employee {
    static void company() {
        System.out.println("OpenAI");
    }
}

Method method = Employee.class.getDeclaredMethod("company");
method.invoke(null);
Output
OpenAI

Static methods belong to the class, hence null is passed as the target.

#Method Metadata

For public int salary():

Java
Method method = Employee.class.getMethod("salary");

System.out.println(method.getName());         // salary
System.out.println(method.getReturnType());   // int

For public void save(String name, int age):

Java
Method method = Employee.class.getMethod("save", String.class, int.class);

System.out.println(method.getParameterCount());   // 2

for (Class<?> c : method.getParameterTypes()) {
    System.out.println(c);
}
Output
class java.lang.String
int

Modifiers:

Java
int modifier = method.getModifiers();

Modifier.isPublic(modifier);
Modifier.isStatic(modifier);
Modifier.isPrivate(modifier);

#Overloaded Methods

Java
class Employee {
    void save() {
    }

    void save(String name) {
    }
}
Java
Employee.class.getDeclaredMethod("save");                 // returns save()
Employee.class.getDeclaredMethod("save", String.class);   // returns save(String)

Reflection differentiates overloaded methods using parameter types.

#Exceptions

ExceptionReason
NoSuchMethodExceptionMethod not found
IllegalAccessExceptionAccess denied
IllegalArgumentExceptionWrong target object or argument types
InvocationTargetExceptionThe invoked method itself threw an exception
Java
try {
    Method method = Employee.class.getMethod("work");
    method.invoke(emp);
} catch (InvocationTargetException e) {
    Throwable real = e.getCause();   // the exception thrown inside work()
} catch (ReflectiveOperationException e) {
    e.printStackTrace();
}

#Internal Working of invoke()

Method object
Access check
Parameter validation
Invoke JVM method
Return result

#Real-World Examples

JUnit

Java
@Test
public void loginTest() {
}

JUnit internally performs operations similar to:

Java
Method method = cls.getDeclaredMethod("loginTest");
method.invoke(testObject);

This is how test methods execute automatically.

Spring Lifecycle Callbacks

Java
@PostConstruct
public void initialize() {
}

Spring does:

Java
Method method = cls.getDeclaredMethod("initialize");
method.invoke(bean);

The framework calls your method without you writing bean.initialize().

Spring MVC

Java
@GetMapping("/users")
public List<User> getUsers() {
}

When an HTTP request arrives, Spring finds getUsers() using Reflection and executes method.invoke(controller).

Mockito

Mockito creates proxy objects. Whenever you call service.save(), Mockito intercepts the call and handles it dynamically using Reflection and proxy (bytecode-generation) mechanisms.

#Interview Questions

Q1Which class represents methods?

java.lang.reflect.Method.

Q2Difference between getMethod() and getDeclaredMethod()?
MethodPublicPrivate
getMethod()✓ (including inherited)✗
getDeclaredMethod()✓ (this class only)✓
Q3Difference between getMethods() and getDeclaredMethods()?
MethodPublicPrivateInherited
getMethods()✓✗✓
getDeclaredMethods()✓✓✗
Q4Which method executes another method?

method.invoke().

Q5Can Reflection invoke private methods?

Yes — by calling setAccessible(true) before invoking the method.

Q6Why does invoke() return Object?

Because Reflection supports invoking methods with any return type. Primitive return values are automatically boxed into wrapper objects.

Q7How do you invoke a static method?

method.invoke(null).

Q8How does Reflection identify overloaded methods?

By the combination of method name and parameter types.

#Key Points to Remember

  • Methods are represented by java.lang.reflect.Method.
  • getMethod() returns only public methods; getDeclaredMethod() returns any declared method.
  • invoke() executes methods dynamically.
  • Static methods use null as the target object.
  • Private methods need setAccessible(true) (subject to modern Java restrictions).
  • Overloaded methods are distinguished by parameter types.
  • JUnit, Spring, Hibernate and Mockito rely heavily on the Method API.

#Chapter Summary

The Method API lets Reflection inspect method metadata and invoke methods dynamically at runtime. It supports public, private, static, overloaded and parameterized methods. This capability is central to frameworks like Spring, JUnit and Mockito, enabling them to execute application logic without compile-time knowledge of the target methods.