Reflection in Java

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Topics Covered

Reflection in Java is a unique feature in the Java programming language that provides us with a way to get information regarding the class to which an object belongs and the methods of that class that can be executed using that object.

We can use Java Reflection to invoke these methods at runtime without knowing their names and change their behaviour at runtime.

java.lang.reflect package

Uses of Reflection

Reflection in Java is a powerful feature with various use cases:

  • It allows classes to be loaded dynamically at runtime, enabling applications to load classes that are not known at compile time.
  • It is commonly used in debugging and testing frameworks to inspect and manipulate objects during runtime, facilitating the creation of generic test cases and debugging tools.
  • Frameworks like Spring use reflection extensively for configuration and dependency injection, allowing developers to define beans and wire dependencies without explicit configuration.
  • It plays a crucial role in serialization and deserialization mechanisms, where objects are converted to and from byte streams. Libraries like Jackson and Gson utilize reflection to map Java objects to JSON and vice versa.

While reflection provides flexibility and power, it should be used judiciously due to its performance overhead and potential security risks.

How to Invoke a Method through Reflection?

Method 1: getDeclaredMethod()

getDeclaredMethod() is a method the Java Reflection API provides. It allows you to obtain a Method object representing a method of a class, including non-public methods.

Method 2: invoke()

The invoke() method, part of Java's Reflection API, executes a method dynamically. It's called on a Method object obtained through reflection, taking the target object instance (or null for static methods) and method arguments as parameters.

Output:

Explanation: In this example, after creating an instance of Employee, we directly obtain the Method object for calculateSalary using getDeclaredMethod(). Then, we set its accessibility to true (if it's private) and invoke it using the invoke() method, passing the instance of Employee and the bonus parameter. Finally, we print the total salary returned using this method.

Method 3: Class.getDeclaredField(FieldName)

The getDeclaredField() method retrieves a Field object representing a declared field of the class. It allows access to non-public fields and accepts the field name as its parameter. This facilitates dynamic access to class fields during runtime via reflection in Java.

Method 4: Field.setAccessible(true)

The setAccessible(accurate) method, employed on a Field object obtained through reflection, enables access to non-public fields. It overrides access restrictions, allowing modification or retrieval of field values that would otherwise be inaccessible due to encapsulation.

Output:

Explanation: In this example, we first obtain the Class object for Employee. Then, we create an instance of Employee using reflection. Next, we use getDeclaredField() to obtain a reference to the private salary field. After making the field accessible, we can get its current value using get() and modify it using set(). Finally, we print the salary field's current and updated values.

Important Points on Reflection API in Java

  1. The Reflection API in Java allows for dynamic inspection and manipulation of classes, interfaces, fields, and methods at runtime.
  2. It provides a way to dynamically analyze and modify the structure and behaviour of Java applications.
  3. Reflection can be used for tasks such as introspecting classes, accessing private members, invoking methods dynamically, and creating instances of classes dynamically.
  4. While powerful, reflection should be used judiciously due to its potential performance overhead and complexity.
  5. It enables frameworks like Spring and Hibernate to perform tasks like dependency injection and object-relational mapping without requiring explicit configuration.
  6. Reflection can be beneficial in scenarios where the structure of classes is not known at compile time, such as in generic programming or plugin systems.
  7. Java's Reflection API is integral to many advanced Java libraries and frameworks, facilitating tasks such as serialization, testing, and debugging.
  8. Security concerns arise with reflection, as it can be used to access sensitive information or modify critical components of a Java application.
  9. Despite its power, developers should strive to minimize the use of reflection in performance-critical code and favour more straightforward, statically-typed alternatives where possible.
  10. Proper understanding and usage of the Reflection API can significantly enhance the flexibility and capabilities of Java applications, but it should be employed thoughtfully and with caution.

Example

Output:

Advantages and Disadvantages of Reflection in Java

Advantages:

  1. It enables dynamic runtime inspection of classes, interfaces, methods, and fields.
  2. It allows the invocation of methods, instantiation of classes, and modification of field values dynamically.
  3. It facilitates the development of Visual Development Environments and class browsers, aiding developers in writing correct code.

Disadvantages:

  1. It violates encapsulation principles by allowing access to private methods and fields, potentially leaking sensitive data.
  2. It introduces performance overhead as types are resolved dynamically, preventing JVM optimization and resulting in slower operations.

Conclusion

  • Reflection in Java is a way through which we can gather information about classes and their methods and alter or modify their behaviour at runtime.
  • It provides dynamic access to class metadata, enabling tasks like instantiation, method invocation, and field manipulation.
  • It supports frameworks and libraries that require runtime analysis and manipulation of classes and objects.
  • It increased flexibility in implementing advanced debugging, logging, and testing functionalities.
  • However, Reflection should be used judiciously due to potential performance overhead, security concerns, and increased code complexity.