Java Reflection
Reflection is a powerful advanced feature provided by Java that allows a running Java program to examine or "reflect upon" itself, and manipulate classes, interfaces, fields, and methods at runtime.
What is Reflection?
The reflection mechanism allows a program at runtime to:
- Get the complete structure of any class (including its parent class, interfaces, constructors, methods, fields, etc.).
- Create instances of any class at runtime.
- Invoke methods of any object at runtime.
- Get or set field values of any object at runtime, even
privatemembers.
The core of reflection is the java.lang.Class class and a series of classes in the java.lang.reflect package, such as Constructor, Method, Field, etc.
The Class Object
For every class loaded into the JVM, a corresponding Class object is created in memory. This Class object contains all information about that class and is the entry point for reflection.
Three Ways to Get a Class Object
-
Using
.classon the class name: The most direct and safest way, checked at compile time. -
Using the
getClass()method on an object: If you already have an object instance, you can call itsgetClass()method. -
Using the fully qualified name with
Class.forName(): This is the most flexible way, allowing dynamic class loading at runtime based on a string.
Using Reflection to Inspect Class Information
Once you have a Class object, you can use it to explore the internal structure of the class.
Using Reflection to Create Instances and Invoke Methods
The most powerful feature of reflection is dynamically creating objects and executing operations at runtime.
Creating Instances
- If the class has a public no-argument constructor, you can directly call
clazz.newInstance()(deprecated) orclazz.getDeclaredConstructor().newInstance(). - If you need to use a parameterized constructor, you first need to get the
Constructorobject.
Invoking Methods
- Get the
Methodobject usinggetMethod()orgetDeclaredMethod(). - Call
method.invoke(object, args...)to execute the method.
Accessing Private Members
Reflection can even bypass private access restrictions. This is useful in unit testing or certain frameworks, but should be used cautiously as it breaks encapsulation.
- Use
getDeclaredField()orgetDeclaredMethod()to get private members. - Before accessing, you must call
setAccessible(true)to disable access security checks.
Pros and Cons of Reflection
Pros:
- Flexibility and dynamism: Enables programs to load, inspect, and use classes unknown at compile time at runtime.
- Framework development: Is the cornerstone of many modern frameworks (such as Spring, Hibernate, JUnit) for implementing dependency injection, ORM, and other features.
Cons:
- Performance overhead: Reflection operations are much slower than direct code calls.
- Security issues: Can bypass access control and break encapsulation.
- Poor code readability: Reflection code is typically more complex and harder to understand and debug.