gpt4 book ai didi

java - 反射将非空属性从一个对象复制到另一个 BeanUtils

转载 作者:行者123 更新时间:2023-11-30 07:07:58 26 4
gpt4 key购买 nike

有这个:

public class Parent {
private String name;
private int age;
private Date birthDate;
private Work work;
static class Work{
private int years;
private String employer;
}

// getters and setters
public static void main(String[] args) {
Parent c = new Parent;
c.setAge(55)
Work work=new Parent.Work();
work.setEmployer("Example");
c.setWork(work);
//save c in a DB...
}
}

我只想使用反射复制非空属性。方法described here with beanUtils 工作得很好,但它复制了所有非空包装对象,而不仅仅是非空字段值:

//fetch c from the db...
Parent sameParent= new Parent;
sameParent.setWork(new Parent.Work());
//Directly from https://stackoverflow.com/questions/1301697/helper-in-order-to-copy-non-null-properties-from-object-to-another-java#answer-3521314
BeanUtilsBean notNull=new NullAwareBeanUtilsBean();
notNull.copyProperties(c, sameParent);

现在,Parent c 将拥有字段 age=55。字段 work.employer 将为空,因为对象 Work 已被覆盖。是否可以修改 BeanUtilsBean 中的 @Override copyProperty 方法以递归地仅从包装对象中复制所需的(非空)属性?

否则,你知道其他方法吗?

最佳答案

您可以通过对该 NullAwareBeanUtilsBean 进行简单调整来实现此目的。我在这里所做的是检查要复制的属性的类型,如果它不是原始类型,则递归调用 copyProperties 方法。 Java 自动装箱将基元转换为其包装类,因此我使用一组来标识基元类型。或者,您可以检查包的类类型以识别自定义对象并仅对自定义进行递归调用,并避免使用所有 java 对象,如 String、Date 等。另请注意,此类不处理原始值。如果目标中的年龄设置为一个值并且源中的年龄未初始化,它仍会覆盖。例如,如果源中的年龄设置为 20 并且未使用新对象设置年龄,则复制会将值 20 覆盖为 0。您可能需要在 if-primitive 检查中为此添加额外的逻辑。

import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtilsBean;

public class NullAwareBeanUtilsBean extends BeanUtilsBean {
private static final Set<Class<?>> primitiveTypes = new HashSet<Class<?>>(
Arrays.asList(Boolean.class, Character.class, Byte.class, Short.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class, String.class, Date.class));

private static final Set<Class<?>> primitiveTypes = new HashSet<Class<?>>() {
{
add(Boolean.class);
add(Character.class);
add(Byte.class);
add(Short.class);
add(Integer.class);
add(Long.class);
add(Float.class);
add(Double.class);
add(Void.class);
}
};

@Override
public void copyProperty(Object dest, String name, Object value)
throws IllegalAccessException, InvocationTargetException {
if (value == null)
return;

if (primitiveTypes.contains(value.getClass())) {
super.copyProperty(dest, name, value);
} else {
try {
Object childObj = getPropertyUtils().getSimpleProperty(dest, name);
if (childObj == null || orig instanceof List && !((List)orig).isEmpty() && ((List)orig).get(0).getClass().isEnum()) {
childObj=orig;
}else{
copyProperties(childObj, orig);
}
super.copyProperty(dest, name, childObj);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
}

关于java - 反射将非空属性从一个对象复制到另一个 BeanUtils,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24371110/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com