Helper是为了将非null属性从对象复制到另一个? (JAVA)
请参阅以下课程
public class Parent { private String name; private int age; private Date birthDate; // getters and setters }
假设我已经创建了一个父对象,如下所示
Parent parent = new Parent(); parent.setName("A meaningful name"); parent.setAge(20);
请注意,根据上面的代码,birthDate属性为null。 现在我想从父对象复制到另一个非空属性。 就像是
SomeHelper.copyNonNullProperties(parent, anotherParent);
我需要它,因为我想更新anotherParent对象而不用空值覆盖其非null。
你知道像这样的帮手吗?
我接受最少的代码作为答案是否没有帮助
问候,
我说你已经有了一个解决方案,因为你问过很多时间。 但是,它没有标记为已解决,也许我可以帮助其他用户。
您是否尝试过定义org.commons.beanutils
包的BeanUtilsBean
的子类? 实际上, BeanUtils
使用这个类,所以这是对dfa提出的解决方案的改进。
检查该类的源代码 ,我认为您可以通过检查空值来覆盖copyProperty
方法,如果值为null copyProperty
执行任何操作。
像这样的东西:
package foo.bar.copy; import java.lang.reflect.InvocationTargetException; import org.apache.commons.beanutils.BeanUtilsBean; public class NullAwareBeanUtilsBean extends BeanUtilsBean{ @Override public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException { if(value==null)return; super.copyProperty(dest, name, value); } }
然后你可以实例化一个NullAwareBeanUtilsBean
并用它来复制你的bean,例如:
BeanUtilsBean notNull=new NullAwareBeanUtilsBean(); notNull.copyProperties(dest, orig);
使用PropertyUtils(commons-beanutils)
for (Map.Entry e : PropertyUtils.describe(parent).entrySet()) { if (e.getValue() != null && !e.getKey().equals("class")) { PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue()); } }
在Java8中:
PropertyUtils.describe(parent).entrySet().stream() .filter(e -> e.getValue() != null) .filter(e -> ! e.getKey().equals("class")) .forEach(e -> { try { PropertyUtils.setProperty(anotherParent, e.getKey(), e.getValue()); } catch (Exception e) { // Error setting property ...; } });
只需使用您自己的复制方法:
void copy(Object dest, Object source) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { BeanInfo beanInfo = Introspector.getBeanInfo(source.getClass()); PropertyDescriptor[] pdList = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pdList) { Method writeMethod = null; Method readMethod = null; try { writeMethod = pd.getWriteMethod(); readMethod = pd.getReadMethod(); } catch (Exception e) { } if (readMethod == null || writeMethod == null) { continue; } Object val = readMethod.invoke(source); writeMethod.invoke(dest, val); } }
如果你的setter的返回类型不是void,那么Apache的BeanUtils将无法工作。 所以将两者结合起来。
package cn.corpro.bdrest.util; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.ConvertUtilsBean; import org.apache.commons.beanutils.PropertyUtilsBean; import org.springframework.beans.BeanUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; /** * Author: BaiJiFeiLong@gmail.com * DateTime: 2016/10/20 10:17 */ public class MyBeanUtils { public static void copyPropertiesNotNull(Object dest, Object orig) throws InvocationTargetException, IllegalAccessException { NullAwareBeanUtilsBean.getInstance().copyProperties(dest, orig); } private static class NullAwareBeanUtilsBean extends BeanUtilsBean { private static NullAwareBeanUtilsBean nullAwareBeanUtilsBean; NullAwareBeanUtilsBean() { super(new ConvertUtilsBean(), new PropertyUtilsBean() { @Override public PropertyDescriptor[] getPropertyDescriptors(Class> beanClass) { return BeanUtils.getPropertyDescriptors(beanClass); } @Override public PropertyDescriptor getPropertyDescriptor(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { return BeanUtils.getPropertyDescriptor(bean.getClass(), name); } }); } public static NullAwareBeanUtilsBean getInstance() { if (nullAwareBeanUtilsBean == null) { nullAwareBeanUtilsBean = new NullAwareBeanUtilsBean(); } return nullAwareBeanUtilsBean; } @Override public void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException { if (value == null) return; super.copyProperty(bean, name, value); } } }
您可以使用Apache Common BeanUtils ,更具体地说是BeanUtils类中的copyProperties助手 :
BeanUtils.copyProperties(parent, anotherParent);
但是为什么你只想要复制非空属性? 如果parent
的属性为null,只需复制它,你也可以在anotherParent
权限中使用null吗?
只是猜测……你想用另一个bean更新bean吗?
我知道这个问题很老了,但我认为以下答案可能对某些人有用。
如果您使用Spring,您可以尝试以下选项。
import java.beans.PropertyDescriptor; import java.util.HashSet; import java.util.Set; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; /** * Helper class to extract property names from an object. * * @Threadsafe * * @author arun.bc * */ public class PropertyUtil { /** * Gets the properties which have null values from the given object. * * @param - source object * * @return - String array of property names. */ public static String[] getNullPropertiesString(Object source) { Set emptyNames = getNullProperties(source); String[] result = new String[emptyNames.size()]; return emptyNames.toArray(result); } /** * Gets the properties which have null values from the given object. * * @param - source object * * @return - Set of property names. */ public static Set getNullProperties(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set emptyNames = new HashSet (); for (PropertyDescriptor pd : pds) { Object srcValue = src.getPropertyValue(pd.getName()); if (srcValue == null) emptyNames.add(pd.getName()); } return emptyNames; } /** * Gets the properties which are not null from the given object. * * @param - source object * * @return - Set array of property names. */ public static Set getNotNullProperties(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set names = new HashSet (); for (PropertyDescriptor pd : pds) { Object srcValue = src.getPropertyValue(pd.getName()); if (srcValue != null) names.add(pd.getName()); } return names; } }
您可以再次使用PropertyDescriptor和上述方法中的Set来修改对象。
肯定 – 使用reflection: http : //java.sun.com/developer/technicalArticles/ALT/Reflection/