[反射] JAVA 替换实体类的属性值,可设置深度

该方法用于将目标对象下的属性的值进行替换。

o 代表 被替换的对象

fieldClass 代表 被替换的属性是什么类型

fieldName 代表 被替换的属性的名称

oldValuenewValue 代表被替换的属性的 旧值 和 新值

deep 代表 替换深度

    /**
     * 替换 对象 属性值
     *
     * @param o          目标对象
     * @param fieldClass 需替换的属性类型
     * @param fieldName  需替换的属性的名称(为null则代表不判断)
     * @param oldValue   需替换的属性原值
     * @param newValue   需替换的属性新值
     * @param deep       可探深度(1代表仅扫描传入Object的属性;2代表传入Object的子属性以及List中每项的属性;3代表更深一层;...以此类推)
     * @apiNote 如果attClass是一个自己的封装类需要重写equals方法
     */
    public static <T> void replaceObjectFieldValue(@NotNull Object o, @NotNull Class<T> fieldClass, String fieldName, T oldValue, T newValue, int deep) {
        if (deep < 1) {
            //超出深度,不再执行该深度的属性值替换
            return;
        }
        //获取属性值
        Field[] declaredFields = o.getClass().getDeclaredFields();
        try {
            //遍历属性
            for (Field declaredField : declaredFields) {
                //设置为可编辑
                declaredField.setAccessible(true);
                //获取属性值
                Object value = declaredField.get(o);
                if (List.class.equals(declaredField.getType())) {
                    if (value == null) {
                        continue;
                    }

                    //是个列表,遍历替换
                    for (Object item : (List) value) {
                        //可探深度减小
                        replaceObjectFieldValue(item, fieldClass, fieldName, oldValue, newValue, deep - 1);
                    }
                } else if (fieldClass.equals(declaredField.getType())) {
                    //是目标属性类型
                    //判断是不是目标属性名
                    if (!(fieldName == null || fieldName.equals(declaredField.getName()))) {
                        //非目标属性名,执行下一个
                        continue;
                    }
                    //判断是否为需替换的目标值
                    if (Objects.equals(oldValue, value)) {
                        //执行替换
                        declaredField.set(o, newValue);
                    }
                } else {
                    if (value == null) {
                        continue;
                    }
                    //是否非基础数据类型
                    if (!isBasicType(value)) {
                        //更深一层执行,可探深度减少
                        replaceObjectFieldValue(value, fieldClass, fieldName, oldValue, newValue, deep - 1);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static boolean isBasicType(Object o) {
        if (o == null) {
            return false;
        } else {
            return o instanceof Integer || o instanceof Short || o instanceof Long || o instanceof Character || o instanceof Byte || o instanceof Boolean || o instanceof BigInteger || o.getClass().getPackage() != null && o.getClass().getPackage().getName().equals("java.math");
        }
    }

举个例子:

     王家有 小明和小小明,现在要改姓为“猛虎王”。⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

    public static void main(String[] args) {

        //王家 有 小明 和 小小明
        Person father = new Person("王", "王", "小明");
        Person son = new Person("王", "王", "小小明");
        Home wangHome = new Home("王", "王", father, son);

        //现在 "王" 改姓 "猛虎王" (⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄)


        //只改Home(不改Home下的Person)                            -- fieldName为null,deep为1
        Home clone1 = wangHome.clone();
        ObjectUtil.replaceObjectFieldValue(clone1, String.class, null, "王", "猛虎王", 1);
        System.out.println(clone1.toString());

        //只改Home(不改Home下的Person),且只改当前姓(不改旧姓)       -- fieldName为"surname",deep为1
        Home clone2 = wangHome.clone();
        ObjectUtil.replaceObjectFieldValue(clone2, String.class, "surname", "王", "猛虎王", 1);
        System.out.println(clone2.toString());

        //全家改,且只改当前姓(不改旧姓)                              -- fieldName为"surname",deep为2
        Home clone3 = wangHome.clone();
        ObjectUtil.replaceObjectFieldValue(clone3, String.class, "surname", "王", "猛虎王", 2);
        System.out.println(clone3.toString());

        //全家改,改当前姓,改旧姓                                      -- fieldName为null,deep为2
        Home clone4 = wangHome.clone();
        ObjectUtil.replaceObjectFieldValue(clone4, String.class, null, "王", "猛虎王", 2);
        System.out.println(clone4.toString());


        //只改小明,不改小小明
        Home clone5 = wangHome.clone();
        Person fatherNew = clone5.father.clone();
        ObjectUtil.replaceObjectFieldValue(fatherNew, String.class, null, "王", "猛虎王", 1);
        //当修改的属性为自定义的class时,强烈建议重写equals方法
        ObjectUtil.replaceObjectFieldValue(clone5, Person.class, "father", clone5.father, fatherNew, 1);
        //或者
        //ObjectUtil.replaceObjectFieldValue(clone5.father, String.class, null, "王", "猛虎王", 2);
        System.out.println(clone5.toString());
    }

    static class Home {
        //家姓
        public String surname;
        //旧姓
        public String oldSurname;
        //父
        public Person father;
        //子
        public Person son;

        public Home(String surname, String oldSurname, Person father, Person son) {
            this.surname = surname;
            this.oldSurname = oldSurname;
            this.father = father;
            this.son = son;
        }

        @Override
        public String toString() {
            return "Home{" +
                    "surname='" + surname + '\'' +
                    ", oldSurname='" + oldSurname + '\'' +
                    ", father=" + father +
                    ", son=" + son +
                    '}';
        }

        @Override
        protected Home clone() {
            return new Home(surname, oldSurname, father.clone(), son.clone());
        }
    }

    static class Person {
        //姓
        public String surname;
        //旧姓
        public String oldSurname;
        //名称
        public String name;

        public Person(String surname, String oldSurname, String name) {
            this.surname = surname;
            this.oldSurname = oldSurname;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "surname='" + surname + '\'' +
                    ", oldSurname='" + oldSurname + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Person) {
                Person o = (Person) obj;
                return o.surname.equals(this.surname) && o.oldSurname.equals(this.oldSurname) && o.name.equals(this.name);
            }
            return super.equals(obj);
        }

        @Override
        protected Person clone() {
            return new Person(surname, oldSurname, name);
        }
    }

结果如下:

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java反射机制可以实现给实体类添加属性,但是这个操作并不是很常见,也不建议这么做。因为Java反射机制是基于类的,而类是静态的,如果在运行时给类添加属性,可能会导致一些不可预测的问题。如果您需要动态地添加属性,可以考虑使用Map集合或者其他动态容器来存储属性。如果您坚持要使用反射机制给实体类添加属性,可以通过以下步骤实现: 1. 获取实体类的Class对象 2. 获取Field数组,即实体类的所有属性 3. 创建新的Field对象,包括属性的名称、类型、修饰符等 4. 将新的Field对象添加到Field数组 5. 使用反射机制设置属性 下面是一个简单的示例代码: ``` public class ReflectTest { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { // 获取实体类的Class对象 Class clazz = User.class; // 获取Field数组 Field[] fields = clazz.getDeclaredFields(); // 创建新的Field对象 Field newField = new Field("newField", String.class, Modifier.PRIVATE); // 将新的Field对象添加到Field数组 Field[] newFields = Arrays.copyOf(fields, fields.length + 1); newFields[fields.length] = newField; // 使用反射机制设置属性 User user = new User(); newField.setAccessible(true); newField.set(user, "newFieldValue"); // 验证属性是否设置成功 System.out.println(user.getNewField()); } } class User { private String name; private int age; // 新添加的属性 private String newField; // getter和setter方法 // ... } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值