java.lang.reflect.Field 类为成员变量的封装类,通过 Field 你可以访问给定对象的类变量,包括获取变量的类型、修饰符、注解、变量名、变量的值或者重新设置变量值,即使变量是private的。

Field 实例获取

Class 类提供了以下四个方法来获取 Field 对象:

  1. public Field[] getFields():获取类的所有public成员变量(包括继承的非私有化成员)
  2. public Field getField(String name):获取指定的public成员变量
  3. public Field[] getDeclaredFields():获取本类的所有的成员变量(仅本类,不包括继承)
  4. public Field getDeclaredField(String name):获取任意访问权限的指定名字的成员

注意:突破权限限制,使用 java.lang.reflect.AccessibleObject 提供的 setAccessible(true) ,该方法的作用就是可以取消 Java 语言访问权限检查。 所以任何继承AccessibleObject (Field、Method、Constructor)的类的对象都可以使用该方法取消 Java 语言访问权限检查。(final类型变量也可以通过这种办法访问)
**

Field 常用方法

  1. 获取属性内容:public Object get(Object obj)
  2. 获取属性类型:public Class<?> getType()
  3. 设置属性内容:public void set(Object obj,Object value)

通过反射调用 set 方法对对象属性进行赋值:

  1. /* User对象 */
  2. public class User implements Serializable {
  3. private String name;
  4. private Integer age;
  5. private boolean man;
  6. private Double money;
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public void setAge(Integer age) {
  11. this.age = age;
  12. }
  13. public void setMan(boolean man) {
  14. this.man = man;
  15. }
  16. public void setMoney(Double money) {
  17. this.money = money;
  18. }
  19. @Override
  20. public String toString() {
  21. return "User{" +
  22. "name='" + name + '\'' +
  23. ", age=" + age +
  24. ", man=" + man +
  25. ", money=" + money +
  26. '}';
  27. }
  28. }
  29. /* 通过字符串使用反射进行赋值 */
  30. public static void main(String[] args) throws Exception {
  31. // 获取 Class 对象
  32. Class<?> clazz = Class.forName("top.songfang.reflect.User");
  33. // 创建实例
  34. User user = (User) clazz.getDeclaredConstructor().newInstance();
  35. // 使用字符串创建对象
  36. String property = "name:张三|age:18|man:true|money:2500.36";
  37. // 1. 拆分字符串
  38. String[] strings = property.split("\\|");
  39. // 2. 对每一个属性进行赋值
  40. for (String string : strings) {
  41. String[] split = string.split(":");
  42. String set = "set" + (split[0].length() == 1 ?
  43. split[0].toUpperCase() :
  44. split[0].substring(0, 1).toUpperCase() + split[0].substring(1));
  45. Field field = clazz.getDeclaredField(split[0]);
  46. Method method = clazz.getDeclaredMethod(set, field.getType());
  47. if ("string".equalsIgnoreCase(field.getType().getSimpleName())) {
  48. method.invoke(user, split[1]);
  49. } else if ("integer".equalsIgnoreCase(field.getType().getSimpleName()) && split[1].matches("\\d+")) {
  50. // 通过正则表达式对传入的字符串进行验证
  51. method.invoke(user, Integer.parseInt(split[1]));
  52. } else if ("double".equalsIgnoreCase(field.getType().getSimpleName()) && split[1].matches("\\d+(\\.\\d{1,2})?")) {
  53. method.invoke(user, Double.parseDouble(split[1]));
  54. } else if ("boolean".equalsIgnoreCase(field.getType().getSimpleName())){
  55. method.invoke(user, "true".equalsIgnoreCase(split[1]));
  56. } else {
  57. throw new RuntimeException("属性无法完成转换!");
  58. }
  59. }
  60. System.out.println(user);
  61. }