Reflection Basics

Inspecting a Class at Runtime

Reflection (java.lang.reflect) lets a program look at and use classes, fields, methods and constructors that it did not know at compile time. Frameworks use it to create your beans, inject fields, map JSON and call controller methods.

Example

The order of getDeclaredFields()/getDeclaredMethods() is not guaranteed, so the example sorts by name.

import java.lang.reflect.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("Customer");
        System.out.println("Class: " + cls.getSimpleName() + ", super: " + cls.getSuperclass().getSimpleName());

        Arrays.stream(cls.getDeclaredFields())
                .sorted(Comparator.comparing(Field::getName))
                .forEach(f -> System.out.println("Field:  " + Modifier.toString(f.getModifiers()) + " "
                        + f.getType().getSimpleName() + " " + f.getName()));
        Arrays.stream(cls.getDeclaredMethods())
                .sorted(Comparator.comparing(Method::getName))
                .forEach(m -> System.out.println("Method: " + m.getName() + " params=" + m.getParameterCount()));

        Object c = cls.getDeclaredConstructor(String.class, int.class).newInstance("Ravi", 1200);
        Method greet = cls.getDeclaredMethod("greet", String.class);
        System.out.println(greet.invoke(c, "Namaste"));

        Field points = cls.getDeclaredField("points");
        points.setAccessible(true);                       // bypass private
        points.setInt(c, 5000);
        System.out.println("After reflection: " + c);
    }
}

class Customer {
    private final String name;
    private int points;
    Customer(String name, int points) { this.name = name; this.points = points; }
    public String greet(String word) { return word + ", " + name + "!"; }
    private boolean isGold() { return points > 1000; }
    public String toString() { return name + " (" + points + " pts)"; }
}

Output

Class: Customer, super: Object
Field:  private final String name
Field:  private int points
Method: greet params=1
Method: isGold params=0
Method: toString params=0
Namaste, Ravi!
After reflection: Ravi (5000 pts)

Costs and Limits

  • Slower than direct calls (mitigated by caching Method objects or using MethodHandle).
  • No compile-time checks: typos in names fail at runtime with NoSuchMethodException.
  • Breaks encapsulation with setAccessible(true); the module system (Java 9+) blocks it for JDK internals unless the package is opens.
  • Use it in libraries and frameworks, rarely in business code.