滥用 Reflection API 来更改私有变量和最终变量
当正确使用反射时,反射非常有用。通过使用反射,你可以访问私有变量并重新初始化最终变量。
以下是代码段,不推荐使用。
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++;
}
}
输出:
A.name=StackOverFlow
A.age=20
A.rep=New Reputation
A.count=25
说明:
在正常情况下,private
变量不能在声明的类之外访问(没有 getter 和 setter 方法)。初始化后无法重新分配 final
变量。
Reflection
打破两个障碍可以被滥用来改变私人和最终变量,如上所述。
field.setAccessible(true)
是实现所需功能的关键。