濫用 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)
是實現所需功能的關鍵。