java.lang.reflect.Field 类为成员变量的封装类,通过 Field 你可以访问给定对象的类变量,包括获取变量的类型、修饰符、注解、变量名、变量的值或者重新设置变量值,即使变量是private的。
Field 实例获取
Class 类提供了以下四个方法来获取 Field 对象:
public Field[] getFields()
:获取类的所有public成员变量(包括继承的非私有化成员)public Field getField(String name)
:获取指定的public成员变量public Field[] getDeclaredFields()
:获取本类的所有的成员变量(仅本类,不包括继承)public Field getDeclaredField(String name)
:获取任意访问权限的指定名字的成员
注意:突破权限限制,使用 java.lang.reflect.AccessibleObject
提供的 setAccessible(true) ,该方法的作用就是可以取消 Java 语言访问权限检查。 所以任何继承AccessibleObject
(Field、Method、Constructor)的类的对象都可以使用该方法取消 Java 语言访问权限检查。(final类型变量也可以通过这种办法访问)
**
Field 常用方法
- 获取属性内容:public Object get(Object obj)
- 获取属性类型:public Class<?> getType()
- 设置属性内容:public void set(Object obj,Object value)
通过反射调用 set 方法对对象属性进行赋值:
/* User对象 */
public class User implements Serializable {
private String name;
private Integer age;
private boolean man;
private Double money;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setMan(boolean man) {
this.man = man;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", man=" + man +
", money=" + money +
'}';
}
}
/* 通过字符串使用反射进行赋值 */
public static void main(String[] args) throws Exception {
// 获取 Class 对象
Class<?> clazz = Class.forName("top.songfang.reflect.User");
// 创建实例
User user = (User) clazz.getDeclaredConstructor().newInstance();
// 使用字符串创建对象
String property = "name:张三|age:18|man:true|money:2500.36";
// 1. 拆分字符串
String[] strings = property.split("\\|");
// 2. 对每一个属性进行赋值
for (String string : strings) {
String[] split = string.split(":");
String set = "set" + (split[0].length() == 1 ?
split[0].toUpperCase() :
split[0].substring(0, 1).toUpperCase() + split[0].substring(1));
Field field = clazz.getDeclaredField(split[0]);
Method method = clazz.getDeclaredMethod(set, field.getType());
if ("string".equalsIgnoreCase(field.getType().getSimpleName())) {
method.invoke(user, split[1]);
} else if ("integer".equalsIgnoreCase(field.getType().getSimpleName()) && split[1].matches("\\d+")) {
// 通过正则表达式对传入的字符串进行验证
method.invoke(user, Integer.parseInt(split[1]));
} else if ("double".equalsIgnoreCase(field.getType().getSimpleName()) && split[1].matches("\\d+(\\.\\d{1,2})?")) {
method.invoke(user, Double.parseDouble(split[1]));
} else if ("boolean".equalsIgnoreCase(field.getType().getSimpleName())){
method.invoke(user, "true".equalsIgnoreCase(split[1]));
} else {
throw new RuntimeException("属性无法完成转换!");
}
}
System.out.println(user);
}