Java Reflection Explained: Classes, Methods, Fields, and Framework Use
Learn Java Reflection with Class, Method, Field, and Constructor APIs, how Spring and JPA use it, performance costs, and safe real-world use.
Last reviewed: August 2026
🔍 What Is It?
Core Reflection Classes:
- →
Class<T>— represents a class; get withobj.getClass()orMyClass.class - →
Method— represents a method; invoke withmethod.invoke(target, args) - →
Field— represents a field; get/set withfield.get(obj)/field.set(obj, value) - →
Constructor<T>— represents a constructor; create withconstructor.newInstance(args) - →
Annotation— represents an annotation; read withelement.getAnnotation(type)
Getting Class Information:
Class<?> clazz = String.class;
clazz.getName() // "java.lang.String"
clazz.getSimpleName() // "String"
clazz.getDeclaredFields() // all fields (including private)
clazz.getFields() // only public fields (including inherited)
clazz.getDeclaredMethods() // all methods (including private)
clazz.getMethods() // only public methods (including inherited)
clazz.getDeclaredAnnotations() // annotations on this class
clazz.getSuperclass() // parent class
clazz.getInterfaces() // implemented interfacesJava 9+ Module System:
Reflection on non-exported packages requires: --add-opens module/package=ALL-UNNAMED or explicit module configuration. Frameworks are adapting to this.
🎯 Why Do We Need It?
Reflection enables generic frameworks:
- →Spring DI — scans classpath for @Component, injects @Autowired fields
- →JPA/Hibernate — maps @Entity fields to database columns
- →Jackson — serializes/deserializes by reading field names and types
- →JUnit — finds @Test methods and invokes them
- →Lombok — generates code based on annotations (at compile time, not reflection)
Without reflection, these frameworks would require explicit configuration for every class — defeating their purpose.
🏗️ What Happens in Real Projects?
As an application developer, you use reflection indirectly:
- →When Spring injects @Autowired dependencies
- →When Jackson serializes your @JsonProperty fields
- →When JPA maps your @Column fields to SQL
- →When you write custom annotation processors
You write reflection code directly for: custom frameworks, testing utilities, serialization libraries, and AOP implementations.
⚙️ How It Works
Reflection Performance:
Reflection is slower than direct code because:
- →Method lookup requires searching the class hierarchy
- →Type checking is done at runtime, not compile time
- →JIT optimization is limited for reflective calls
Mitigation:
- →Cache Method/Field objects after first lookup
- →Use MethodHandles (Java 7+) — faster than reflection for repeated calls
- →Use invokedynamic — how lambdas are implemented
Access Control:
field.setAccessible(true) bypasses private/protected access modifiers. This is how Spring injects @Autowired private fields. In Java 9+, this requires module system permissions.
💻 Example
Reflection in Practice — How reflection powers framework features and how to use it safely.
🤔 Common Confusions
❓ Is reflection slow? Should I avoid it?
Reflection is slower than direct code — typically 10-100x for method invocation. However, this matters only in hot paths (called millions of times per second). Framework initialization (Spring startup) uses reflection but only runs once. Jackson serializes millions of objects but caches the reflection metadata. In application code, reflection is fine if you cache Method/Field objects. Never use reflection in tight loops.
❓ What is the difference between getFields() and getDeclaredFields()?
getDeclaredFields() returns all fields declared in this class (including private, protected, package-private) but NOT inherited fields. getFields() returns all public fields of this class AND all public inherited fields. For accessing private fields, use getDeclaredFields() + setAccessible(true). For a complete picture of all fields including inherited, iterate up the class hierarchy using getSuperclass().
🚨 Common Production Issues
Performance in tight loops — calling method.invoke() in a loop processing millions of records is slow. Cache Method objects; consider MethodHandles for better JIT optimization.
Java 9+ module system breaking reflection — accessing non-exported packages throws InaccessibleObjectException. Requires --add-opens or module configuration.
Security manager restrictions — in some environments (application servers, security-hardened JVMs), setAccessible(true) may be denied.
✅ Best Practices
Cache Method, Field, and Constructor objects — lookup is expensive; invocation is cheaper.
Use MethodHandles instead of Method.invoke() for performance-critical reflection.
Prefer annotation processors (compile-time) over runtime reflection when possible.
Do not use reflection in application business logic — use it only for framework/infrastructure code.
Handle InaccessibleObjectException gracefully for Java 9+ module compatibility.
🏛️ Architect's Note
Modern Java frameworks are moving away from runtime reflection toward compile-time code generation (Lombok, MapStruct, Quarkus, Micronaut). Compile-time approaches: faster startup (no classpath scanning), better GraalVM Native Image compatibility, and better IDE support. Spring Boot 3+ supports AOT (Ahead-Of-Time) compilation which pre-processes reflection at build time for faster startup and native image support.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
Core Java Interview Prep
Practice interview questions that connect directly to this technology track.
↗ Where this topic fits
Core Java Technology Guide
Return to the Core Java learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Core Java references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Core Java learning path
Browse the full Core Java topic collection and learning order on SplashRide.
Core Java Interview Prep
Practice Core Java interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Classes & Objects
The foundation of Java OOP — how classes define blueprints and objects are instances, with constructors, fields, methods, and the this keyword.
Generics
Java Generics — type parameters, bounded wildcards, type erasure, and how generics make collections and APIs type-safe.