Reflection in Java is a powerful feature that allows a program to inspect and modify its own structure or behavior at runtime. It is commonly used in advanced Java applications for tasks such as analyzing classes, methods, fields, or for creating dynamic proxies.
Reflection is part of the java.lang.reflect package and is widely used in frameworks like Hibernate, Spring, and JUnit.
Reflection relies on several key classes, including:
You can obtain a Class object for a given class using the following methods:
Example:
public class ReflectionExample { public static void main(String[] args) { try { // Obtain Class object using Class.forName() Class> clazz = Class.forName("java.util.ArrayList"); // Print class name System.out.println("Class Name: " + clazz.getName()); // Check if it is an interface System.out.println("Is Interface: " + clazz.isInterface()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
You can access and manipulate fields of a class using the Field class. Private fields can be accessed by setting them accessible using setAccessible(true).
Example:
import java.lang.reflect.Field; public class FieldExample { public static void main(String[] args) { try { Class> clazz = Class.forName("java.awt.Point"); Field field = clazz.getDeclaredField("x"); // Set field accessible field.setAccessible(true); // Access field value Object point = clazz.getConstructor().newInstance(); System.out.println("Initial x: " + field.get(point)); // Modify field value field.set(point, 10); System.out.println("Modified x: " + field.get(point)); } catch (Exception e) { e.printStackTrace(); } } }
The Method class allows you to invoke methods dynamically. This is useful for calling methods at runtime without knowing their names beforehand.
Example:
import java.lang.reflect.Method; public class MethodExample { public static void main(String[] args) { try { Class> clazz = Class.forName("java.lang.String"); Method method = clazz.getMethod("substring", int.class); // Invoke method String str = "Hello, Reflection!"; Object result = method.invoke(str, 7); System.out.println("Result: " + result); } catch (Exception e) { e.printStackTrace(); } } }
The Constructor class is used to create new instances of a class dynamically.
Example:
import java.lang.reflect.Constructor; public class ConstructorExample { public static void main(String[] args) { try { Class> clazz = Class.forName("java.lang.String"); // Get constructor with byte array parameter Constructor> constructor = clazz.getConstructor(byte[].class); // Create new instance byte[] data = "Dynamic String".getBytes(); String str = (String) constructor.newInstance((Object) data); System.out.println("Created String: " + str); } catch (Exception e) { e.printStackTrace(); } } }
Reflection is commonly used in the following scenarios:
Reflection is a versatile tool in Advanced Java that enables developers to build dynamic and flexible applications. While powerful, it should be used cautiously as it can impact performance and security if not handled properly.