In Advanced Java, the Reflection API allows you to access fields, methods, and constructors of classes dynamically at runtime. This feature is widely used in frameworks, libraries, and tools to analyze or manipulate objects without knowing their structure beforehand.
Fields (or member variables) of a class can be accessed and modified dynamically using the Field class from the java.lang.reflect package. Both public and private fields can be manipulated.
Example:
import java.lang.reflect.Field; class Person { private String name = "Default Name"; } public class AccessFields { public static void main(String[] args) { try { // Obtain Class object Class> clazz = Person.class; // Get the field Field field = clazz.getDeclaredField("name"); // Make the field accessible field.setAccessible(true); // Create an instance of the class Person person = new Person(); // Get and print the field value System.out.println("Initial Value: " + field.get(person)); // Modify the field value field.set(person, "John Doe"); System.out.println("Modified Value: " + field.get(person)); } catch (Exception e) { e.printStackTrace(); } } }
Methods of a class can be invoked dynamically using the Method class. This is particularly useful when method names or parameters are determined at runtime.
Example:
import java.lang.reflect.Method; class Calculator { public int add(int a, int b) { return a + b; } } public class AccessMethods { public static void main(String[] args) { try { // Obtain Class object Class> clazz = Calculator.class; // Get the method Method method = clazz.getMethod("add", int.class, int.class); // Create an instance of the class Calculator calculator = new Calculator(); // Invoke the method Object result = method.invoke(calculator, 5, 10); System.out.println("Result: " + result); } catch (Exception e) { e.printStackTrace(); } } }
Constructors can be used to create new instances of a class dynamically using the Constructor class.
Example:
import java.lang.reflect.Constructor; class Person { private String name; // Constructor public Person(String name) { this.name = name; } public String getName() { return name; } } public class AccessConstructors { public static void main(String[] args) { try { // Obtain Class object Class> clazz = Person.class; // Get the constructor Constructor> constructor = clazz.getConstructor(String.class); // Create a new instance Person person = (Person) constructor.newInstance("Jane Doe"); // Print the created object's details System.out.println("Name: " + person.getName()); } catch (Exception e) { e.printStackTrace(); } } }
Reflection allows you to combine access to fields, methods, and constructors dynamically to build flexible and dynamic applications.
Example:
import java.lang.reflect.*; class Example { private String message; public Example(String message) { this.message = message; } public void printMessage() { System.out.println("Message: " + message); } } public class CombinedReflection { public static void main(String[] args) { try { // Obtain Class object Class> clazz = Example.class; // Access the constructor Constructor> constructor = clazz.getConstructor(String.class); Object example = constructor.newInstance("Hello, Reflection!"); // Access the field Field field = clazz.getDeclaredField("message"); field.setAccessible(true); // Modify the field value field.set(example, "Updated Message!"); // Access the method Method method = clazz.getMethod("printMessage"); // Invoke the method method.invoke(example); } catch (Exception e) { e.printStackTrace(); } } }
Reflection is commonly used in:
However, it is important to use reflection cautiously because:
Accessing fields, methods, and constructors dynamically using reflection is a powerful tool in Advanced Java. It allows developers to build flexible and dynamic applications but requires careful use to avoid potential issues.