Methods in Reflection
The Method API — getMethods vs getDeclaredMethods, invoking public, private, static and parameterized methods, return values, overloads, InvocationTargetException and framework usage.
#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.
class Employee {
public void work() {
System.out.println("Working...");
}
public int salary() {
return 50000;
}
}Normally:
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.
#Getting Methods
public class Employee {
public void work() {}
public void display() {}
private void secret() {}
}getMethods() — Public, Including Inherited
Class<?> cls = Employee.class;
Method[] methods = cls.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}work
display
wait
equals
hashCode
toString
notifyNotice: methods inherited from Object are also returned.
getDeclaredMethods() — Declared in This Class Only
Method[] methods = Employee.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}work
display
secretOnly methods declared inside Employee are returned — including the private one. (The order of returned methods isn't guaranteed.)
getMethods() vs getDeclaredMethods()
| Method | Public | Private | Inherited |
|---|---|---|---|
getMethods() | ✓ | ✗ | ✓ |
getDeclaredMethods() | ✓ | ✓ | ✗ |
#Getting a Specific Method
class Employee {
public void work() {
}
}
Method method = Employee.class.getMethod("work");A Private Method
class Employee {
private void secret() {
}
}
Method method = Employee.class.getDeclaredMethod("secret");
method.setAccessible(true);Now Reflection can invoke it.
A Parameterized Method
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
class Employee {
public void work() {
System.out.println("Working");
}
}
Employee emp = new Employee();
Method method = Employee.class.getMethod("work");
method.invoke(emp);WorkingReflection executed the method dynamically.
With Parameters
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");Hello RahulArguments are supplied at runtime.
Returning a Value
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);50000Notice: invoke() always returns Object. Primitive return values are automatically boxed (here an Integer), and void methods return null.
A Private Method
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);HiddenReflection bypasses access checks (subject to module/security restrictions in modern Java).
A Static Method
class Employee {
static void company() {
System.out.println("OpenAI");
}
}
Method method = Employee.class.getDeclaredMethod("company");
method.invoke(null);OpenAIStatic methods belong to the class, hence null is passed as the target.
#Method Metadata
For public int salary():
Method method = Employee.class.getMethod("salary");
System.out.println(method.getName()); // salary
System.out.println(method.getReturnType()); // intFor public void save(String name, int age):
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);
}class java.lang.String
intModifiers:
int modifier = method.getModifiers();
Modifier.isPublic(modifier);
Modifier.isStatic(modifier);
Modifier.isPrivate(modifier);#Overloaded Methods
class Employee {
void save() {
}
void save(String name) {
}
}Employee.class.getDeclaredMethod("save"); // returns save()
Employee.class.getDeclaredMethod("save", String.class); // returns save(String)Reflection differentiates overloaded methods using parameter types.
#Exceptions
| Exception | Reason |
|---|---|
NoSuchMethodException | Method not found |
IllegalAccessException | Access denied |
IllegalArgumentException | Wrong target object or argument types |
InvocationTargetException | The invoked method itself threw an exception |
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()
#Real-World Examples
JUnit
@Test
public void loginTest() {
}JUnit internally performs operations similar to:
Method method = cls.getDeclaredMethod("loginTest");
method.invoke(testObject);This is how test methods execute automatically.
Spring Lifecycle Callbacks
@PostConstruct
public void initialize() {
}Spring does:
Method method = cls.getDeclaredMethod("initialize");
method.invoke(bean);The framework calls your method without you writing bean.initialize().
Spring MVC
@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()?
| Method | Public | Private |
|---|---|---|
getMethod() | ✓ (including inherited) | ✗ |
getDeclaredMethod() | ✓ (this class only) | ✓ |
Q3Difference between getMethods() and getDeclaredMethods()?
| Method | Public | Private | Inherited |
|---|---|---|---|
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
nullas 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.