Reflection is useful when it is properly used for right purpose. By using reflection, you can access private variables and re-initialize final variables.
Below is the code snippet, which is not recommended.
import java.lang.reflect.*;
public class ReflectionDemo{
public static void main(String args[]){
try{
Field[] fields = A.class.getDeclaredFields();
A a = new A();
for ( Field field:fields ) {
if(field.getName().equalsIgnoreCase("name")){
field.setAccessible(true);
field.set(a, "StackOverFlow");
System.out.println("A.name="+field.get(a));
}
if(field.getName().equalsIgnoreCase("age")){
field.set(a, 20);
System.out.println("A.age="+field.get(a));
}
if(field.getName().equalsIgnoreCase("rep")){
field.setAccessible(true);
field.set(a,"New Reputation");
System.out.println("A.rep="+field.get(a));
}
if(field.getName().equalsIgnoreCase("count")){
field.set(a,25);
System.out.println("A.count="+field.get(a));
}
}
}catch(Exception err){
err.printStackTrace();
}
}
}
class A {
private String name;
public int age;
public final String rep;
public static int count=0;
public A(){
name = "Unset";
age = 0;
rep = "Reputation";
count++;
}
}
Output:
A.name=StackOverFlow
A.age=20
A.rep=New Reputation
A.count=25
Explanation:
In normal scenario, private
variables can't be accessed outside of declared class ( without getter and setter methods). final
variables can't be re-assigned after initialization.
Reflection
breaks both barriers can be abused to change both private and final variables as explained above.
field.setAccessible(true)
is the key to achieve desired functionality.