org.springframework.beans.BeanUtils的一个demo。可以很优雅的实现将父类字段的值copy到子类中 下面例子的输出结果(子类使用父类的toString方法,有点意思吧):
true Person{name=‘people‘}
import org.springframework.beans.BeanUtils; public class Test { public static void main(String[] args) { Person person = new Person("people"); Male male = new Male(); BeanUtils.copyProperties(person, male); System.out.println(Male.class.isInstance(male)); System.out.println(male); } } class Person { private String name; public Person() { } public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name=‘" + name + ‘\‘‘ + ‘}‘; } } class Male extends Person { private String necklace; public Male() { } public Male(String name) { super(name); } public String getNecklace() { return necklace; } public void setNecklace(String necklace) { this.necklace = necklace; } }
org.springframework.beans.BeanUtils
源码解析:
使用的是反射:
/** * Copy the property values of the given source bean into the target bean. * <p>Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. * <p>This is just a convenience method. For more complex transfer needs, * consider using a full BeanWrapper. * @param source the source bean * @param target the target bean * @throws BeansException if the copying failed * @see BeanWrapper */ public static void copyProperties(Object source, Object target) throws BeansException { copyProperties(source, target, null, (String[]) null); }
/** * Copy the property values of the given source bean into the given target bean. * <p>Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. * @param source the source bean * @param target the target bean * @param editable the class (or interface) to restrict property setting to * @param ignoreProperties array of property names to ignore * @throws BeansException if the copying failed * @see BeanWrapper */ private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties) throws BeansException { Assert.notNull(source, "Source must not be null"); Assert.notNull(target, "Target must not be null"); Class<?> actualEditable = target.getClass(); if (editable != null) { if (!editable.isInstance(target)) { throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]"); } actualEditable = editable;//如果editable赋值,则ignore Target中的字段属性 } PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable); List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); for (PropertyDescriptor targetPd : targetPds) { Method writeMethod = targetPd.getWriteMethod(); if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) { 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); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, value); } catch (Throwable ex) { throw new FatalBeanException( "Could not copy property ‘" + targetPd.getName() + "‘ from source to target", ex); } } } } } }
时间: 2024-10-24 15:15:45