该方法用于将目标对象下的属性的值进行替换。
o 代表 被替换的对象
fieldClass 代表 被替换的属性是什么类型
fieldName 代表 被替换的属性的名称
oldValue 和 newValue 代表被替换的属性的 旧值 和 新值
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);
}
}
结果如下: