Reflection
Reflection in Java provides a way to change/modify the state of an object in runtime.
Helps to inspect the classes and look/modify the fields even if they are marked as private and final
Dynamically invoke methods on objects, even private methods, at runtime
What are some practical use case of Reflections?
Getting name fields:
import java.lang.reflect.Field;
public class Reflection {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Cat myCat = new Cat("Fred", 3);
System.out.println("Initially");
System.out.println(myCat);
System.out.println("###########################");
// Iterating through all the fields by calling getDeclaredFields
Field[] fields = myCat.getClass().getDeclaredFields();
for(Field field: fields) {
// System.out.println(field.getName()); // Prints the field name
if(field.getName().equals("name")) {
field.set(myCat, "Mercury");
}
}
System.out.println("After setting name with reflection loop");
System.out.println(myCat);
System.out.println("###########################");
// Get a field name based on the given name
Field ageField = myCat.getClass().getDeclaredField("age");
ageField.set(myCat, 6);
System.out.println("After setting age with reflection getField");
System.out.println(myCat);
}
static class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
Output:
Initially
Cat{name='Fred', age=3}
###########################
After setting name with reflection loop
Cat{name='Mercury', age=3}
###########################
After setting age with reflection getField
Cat{name='Mercury', age=6}
Invoking methods
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Reflection {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Cat myCat = new Cat("Fred", 3);
// Gets the methods in an array
Method[] methods = myCat.getClass().getDeclaredMethods();
for (Method method: methods) { // Loop through the array
if(method.getName().equals("privateMethod")) {
method.setAccessible(true); // If it is private, set it to method.setAccessible(true)
method.invoke(myCat, "Mercury"); // Invoke the method by passing the clas and relevant parameters
} else if(method.getName().equals("privateStaticMethod")) {
method.setAccessible(true);
method.invoke(null); // If it's a static method, invoke the method with null
}
}
}
static class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
private void privateMethod(String name) {
System.out.println("I am a private method with name: " + name);
}
private static void privateStaticMethod() {
System.out.println("I am a private STATIC method");
}
}
}
Output
I am a private method with name: Mercury
I am a private STATIC method
Usecases:
Framework Development: Frameworks often need to work with various classes and their properties without knowing them in advance. Reflection helps achieve this flexibility.
Generic Programming: Reflection allows writing code that operates on different types of objects without explicitly handling each type.
Dynamic Class Loading: You can load classes dynamically based on user input or configuration at runtime using reflection.
Issues with Reflection
Reflection often causes performance overhead, as it needs to iteratre through all the fields or methods during runtime
It might break the codebase as the behaviour might not be consistent, if implemented haphazardly
Modifying private fields or invoking private methods out of the context could be a serious cause of concern for security.
Last updated
Was this helpful?