Reflection is an API which help us to analyze and modify the behavior of a class at runtime. It provides us methods which can be used to achieve the desired behavior.
Object Creation:
Reflection API provide us methods which can fetch list of constructors available of a class and can be used to create objects. Constructors are represented as Constructor.java class.
getConstructors(): This method returns the list of public constructors of a class.
getDeclaredConstructors(): This method returns the list of all constructors irrespective of access modifiers.
getConstructor(arg): This method returns the public constructor matching the argument provided.
getDeclaredConstructors(): This method returns the list of all constructors irrespective of access modifiers.
getDeclaredConstructor(arg): This method returns the constructor matching the argument provided.
setAccessible(true): We can use this method to instantiate objects using constructors which are otherwise not accessible due to access modifiers restrictions like private constructors.
Refer the code below –
public class ReflectionDemo {
private int data;
private ReflectionDemo(int num) {
this.data = num;
}
public void testMethod() {
System.out.println("Current data value == " + this.data);
}
}
public class ReflectionMain {
public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<ReflectionDemo> reflectionDemoConstructor =
ReflectionDemo.class.getDeclaredConstructor(int.class);
// required for private constructors or constructors which are not accessible based on access modifiers,
// helps in singleton approaches
reflectionDemoConstructor.setAccessible(true);
ReflectionDemo demo = reflectionDemoConstructor.newInstance(10);
demo.testMethod();
}
Reflection on Fields:
Reflection API provide us methods which can fetch list of fields available in a class. Fields are represented as Field.java class.
getFields(): This method returns the list of public fields of a class.
getDeclaredFields(): This method returns the list of all fields irrespective of access modifiers.
getField(“field_name“): This method returns the Field.java object of the field matching the name provided in argument.
getDeclaredFields(): This method returns the list of all fields irrespective of access modifiers.
getDeclaredField(“field_name“): This method returns the Field.java object of the field matching the argument provided.
setAccessible(true): We can use this method to access fields which are not accessible due to access modifiers restrictions like private fields.
Once we get the Field.java object from one of the above methods we can use the get(<object_instance>) and set(<object_instance>, <value>) method to get and set the value of the field in the given object instance respectively. Now you might be wondering why would we do that if we already have object? Yes true we don’t need that as long the field is accessible but using setAccessible(true) you can also get value of private variable which is not possible otherwise.
Refer the code below, add it in above main method and observe the output –
Field[] declaredFields = ReflectionDemo.class.getDeclaredFields();
System.out.println("Declared fields ==> " + declaredFields.length + "::" + Arrays.toString(declaredFields));
Field temp = declaredFields[0]; // Fetching the "data" field
temp.setAccessible(true); // Since data field is private
System.out.println("Value of data :: " + temp.get(demo));
temp.set(demo, 2000);
System.out.println("Updated Value of data :: " + temp.get(demo));