- 問題描述
開發在中進程經常需要將一個對象的若干個值賦值給另外一個對象相對應的字段,且字段名是一樣的,如果一個一個取一個一個賦值太麻煩。有很多類似與org.springframework.beans.BeanUtils的工具類,提供了copyProperties方法,但通過測試發現他會將拷貝對象中的null也拷貝過去,在做一些對象數據更新的操作,我們往往只更新需要更新的值,這時我們就不想拷貝對象中null也被拷貝到目標對象中。
- 解決辦法
通過對org.springframework.beans.BeanUtils的copyProperties源碼觀察,我們稍作修改就能夠達到上述的目的,在拷貝前多加一句判斷,下面是封裝的工具類
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Modifier;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* BeanUtils 可以實現copyProperties 拷貝對象的 null 不復制。
* @author Fate
* @version 1.0
* @date 2020/7/15 22:52
*/
public class MyBeanUtils extends BeanUtils {
public static void copyProperties(Object source, Object target) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
PropertyDescriptor[] var7 = targetPds;
int var8 = targetPds.length;
for (int var9 = 0; var9 < var8; ++var9) {
PropertyDescriptor targetPd = var7[var9];
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
// 判斷value是否為空
if (value != null) {
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
} catch (Throwable var15) {
throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var15);
}
}
}
}
}
}
}
-
總結
經過測試能實現問題描述的目的,但應該有更好的解決辦法,有待改進....