Reflection in Java is a powerful feature that allows programs to inspect and modify classes, methods, fields, and constructors at runtime—even if they are private.
📌 Key Capabilities of Reflection:
- Discover class information dynamically (methods, fields, constructors).
- Invoke methods dynamically (even private ones).
- Modify fields dynamically (even private ones).
- Create objects dynamically without using
new
.
1. Why Use Reflection?
Use Case | Why Use Reflection? |
---|---|
Frameworks (Spring, Hibernate, JUnit) | Dynamically inject dependencies, test methods, etc. |
Serialization & Deserialization | Convert objects to XML/JSON (Jackson , Gson ). |
Dynamic Method Invocation | Call methods even if their names are unknown at compile time. |
Class Loaders & Plugins | Load new classes dynamically without modifying existing code. |
2. Accessing Class Information Using Reflection
The Class
class in Java provides methods to inspect a class at runtime.
✅ Example: Getting Class Information
class Person {
private String name;
public int age;
public Person() {} // Default constructor
}
public class ReflectionExample {
public static void main(String[] args) {
Class<?> clazz = Person.class; // Get class object
System.out.println("Class Name: " + clazz.getName()); // Full class name
System.out.println("Simple Name: " + clazz.getSimpleName()); // Short name
// Get all declared fields
System.out.println("Fields:");
for (var field : clazz.getDeclaredFields()) {
System.out.println(field.getName() + " (" + field.getType() + ")");
}
}
}
✅ Output:
Class Name: Person
Simple Name: Person
Fields:
name (class java.lang.String)
age (int)
📌 Key Takeaways:
Class<?> clazz = Person.class;
Gets the class object..getDeclaredFields()
Gets private and public fields.
3. Creating Objects Dynamically
Reflection allows creating objects without using new
.
✅ Example: Instantiating a Class at Runtime
class Car {
public Car() {
System.out.println("Car Object Created!");
}
}
public class DynamicObjectCreation {
public static void main(String[] args) throws Exception {
Class<?> clazz = Car.class;
Object obj = clazz.getDeclaredConstructor().newInstance(); // Create object dynamically
}
}
✅ Output:
Car Object Created!
📌 Why is this useful?
- Used in frameworks (Spring, Hibernate) for dependency injection.
4. Accessing & Modifying Private Fields
Reflection allows modifying private fields, even though they are not normally accessible.
✅ Example: Changing a Private Field
import java.lang.reflect.Field;
class Secret {
private String message = "This is private";
void printMessage() {
System.out.println(message);
}
}
public class ModifyPrivateField {
public static void main(String[] args) throws Exception {
Secret secret = new Secret();
secret.printMessage(); // This is private
// Access private field using reflection
Field field = Secret.class.getDeclaredField("message");
field.setAccessible(true); // Make it accessible
field.set(secret, "Modified Secret Message");
secret.printMessage(); // Modified Secret Message
}
}
✅ Output:
This is private
Modified Secret Message
📌 Why is this useful?
- Used in testing frameworks (JUnit, Mockito) to modify private fields.
5. Invoking Methods Dynamically
Reflection allows calling methods dynamically—even if their names are unknown at compile time.
✅ Example: Calling a Method by Name
import java.lang.reflect.Method;
class Greet {
private void sayHello(String name) {
System.out.println("Hello, " + name);
}
}
public class DynamicMethodInvocation {
public static void main(String[] args) throws Exception {
Greet greet = new Greet();
// Get method reference
Method method = Greet.class.getDeclaredMethod("sayHello", String.class);
method.setAccessible(true); // Bypass private restriction
// Invoke method
method.invoke(greet, "Alice");
}
}
✅ Output:
Hello, Alice
📌 Why is this useful?
- Used in JVM-based frameworks (JUnit, Spring, Hibernate).
6. Working with Constructors
Reflection allows retrieving and using constructors dynamically.
✅ Example: Getting & Using a Constructor
import java.lang.reflect.Constructor;
class Product {
String name;
public Product(String name) {
this.name = name;
}
}
public class ConstructorReflection {
public static void main(String[] args) throws Exception {
Constructor<Product> constructor = Product.class.getConstructor(String.class);
Product product = constructor.newInstance("Laptop");
System.out.println("Product: " + product.name);
}
}