BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ OOP and types

Java language

Reflection

Reflection lets code look at classes, methods and fields by name at run time, and call or change them, without knowing them at compile time.

Learn these first

At a glance

Mental model

Instead of knowing the staff by name, you walk into the building with a directory: "find everybody whose badge says Manager, and ask each one to sign this".

What happens, in order
  1. 1Class<?> c = Class.forName("com.shop.Order") or Order.class gets the class objectc.getDeclaredMethods(), getDeclaredFields() and getDeclaredConstructor() list its members.
  2. 2method.invoke(target, args) calls a method; field.set(obj, value) writes a field; constructor.newInstance(args) creates an object
  3. 3setAccessible(true) bypasses privateModern Java restricts this for JDK internals through the module system.
  4. 4Annotation processing at run time is reflection: m.isAnnotationPresent(Test.class) is how test runners find tests
Remember
Watch out
Catching InvocationTargetException and forgetting to look at getCause()Looking up members by string and losing refactoring safetyCalling getMethods() repeatedly in a hot path instead of caching
Example (highlighted lines explain it)
import java.lang.reflect.Method;public class Runner {  static void runAll(Object target) throws Exception {    for (Method m : target.getClass().getDeclaredMethods()) {      if (m.isAnnotationPresent(Deprecated.class)) continue;      m.setAccessible(true);      if (m.getParameterCount() == 0) m.invoke(target);    }  }}
  1. line 1 uses Method, the core of Reflection
  2. line 4 uses Method, the core of Reflection
  3. line 5 uses isAnnotationPresent, the core of Reflection
  4. line 6 uses setAccessible, the core of Reflection
  5. line 7 uses invoke, the core of Reflection
Read the full explanation (about 1 min)

Reflection lets code look at classes, methods and fields by name at run time, and call or change them, without knowing them at compile time. Frameworks use it to find your annotated classes and create your objects.

A mental model

Instead of knowing the staff by name, you walk into the building with a directory: "find everybody whose badge says Manager, and ask each one to sign this".

How it works

Class<?> c = Class.forName("com.shop.Order") or Order.class gets the class object. c.getDeclaredMethods(), getDeclaredFields() and getDeclaredConstructor() list its members.

method.invoke(target, args) calls a method; field.set(obj, value) writes a field; constructor.newInstance(args) creates an object.

setAccessible(true) bypasses private. Modern Java restricts this for JDK internals through the module system.

Annotation processing at run time is reflection: m.isAnnotationPresent(Test.class) is how test runners find tests.

Going deeper

Reflection hides dependencies from the compiler: renaming a method breaks code that looks it up by a string, and the error appears only at run time. It is also slower than a direct call and defeats some optimisations, so cache Method objects.

Security: reflective access to private members can break encapsulation; never build class names or method names from user input.

For code that must run fast, prefer method handles or generate code; GraalVM native-image needs reflection to be declared up front.

Under the hood

Class objects are created by the class loader. After a few calls Method.invoke is compiled to a generated accessor, and since Java 18 it uses method handles. Exceptions from the target method are wrapped in InvocationTargetException.

Common mistakes

  • Catching InvocationTargetException and forgetting to look at getCause().
  • Looking up members by string and losing refactoring safety.
  • Calling getMethods() repeatedly in a hot path instead of caching.

How Unravel recognises it

When you paste code, Unravel looks for these signs of reflection. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Builds on this

Frequently asked questions

What is Reflection?

Reflection lets code look at classes, methods and fields by name at run time, and call or change them, without knowing them at compile time. Frameworks use it to find your annotated classes and create your objects.

What are the most common mistakes with Reflection?

Catching InvocationTargetException and forgetting to look at getCause(). Looking up members by string and losing refactoring safety. Calling getMethods() repeatedly in a hot path instead of caching.

How can I see Reflection in real code?

Paste your own Java into Unravel and it will point out where reflection appears, explain how it works at the detail level you choose, and draw the flow of the code around it.