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;}@Overridepublic 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);}
