通常为了保证面向对象的封装特性,我们一般将Bean中的字段设置成私有的,然后提供对应的get和set方法对字段进行控制。
下面学习如何利用反射来对对象的私有字段进行控制,达到运行时修改类的私有字段的目的。
关键点:
如果我们想对一个Class类型的对象的字段进行处理,我们必须获得这个类型的Field对象,然后通过调用它的下面方法进行操作:
set(Object obj,Object value);将指定对象变量上次Field的对象表示的字段设置为指定的新值
setBoolean(Object obj,boolean z);将字段的值设置为指定的boolean类型的值
setDouble(Object obj,double e); 将字段的值设置为double值
setInt(Object obj,int i);将字段的值设置为int值
setAccessible(boolean flag);将此对象的accessible标志设置为指定的布尔值,对于私有字段,一定要先将accessible设置为true才可以对其进行操作
首先,我们先编写一个Bean:
package ReflectStudy.Exa145;
public class Student {
private int id;
private String name;
private boolean male;
private double account;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isMale() {
return male;
}
public void setMale(boolean male) {
this.male = male;
}
public double getAccount() {
return account;
}
public void setAccount(double account) {
this.account = account;
}
}
然后进行反射编程操作它:
package ReflectStudy.Exa145;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setId(8);
student.setAccount(20);
student.setMale(true);
student.setName("麻子");
//获得得student对象的Class对象
Class<?> clazz = student.getClass();
System.out.println("类的标准名称:" + clazz.getCanonicalName());
try {
//得到对象中名为id的字段对象
Field id = clazz.getDeclaredField("id");
System.out.println("设置前的id:" + student.getId());
id.setAccessible(true);
id.setInt(student, 10);
System.out.println("设置后的id:" + student.getId());
Field name = clazz.getDeclaredField("name");
System.out.println("设置前的name:" + student.getName());
name.setAccessible(true);
name.set(student, "四郎");
System.out.println("设置后的name:" + student.getName());
Field male = clazz.getDeclaredField("male");
System.out.println("设置前的male:" + student.isMale());
male.setAccessible(true);
male.setBoolean(student, false);
System.out.println("设置后的male:" + student.isMale());
Field account = clazz.getDeclaredField("account");
System.out.println("设置前的account:" + student.getAccount());
account.setAccessible(true);
account.setDouble(student, 45.67);
System.out.println("设置后的account:" + student.getAccount());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
运行之: