java对象拷贝

来源:互联网 发布:java生产管理系统 编辑:程序博客网 时间:2024/06/06 13:00
package com.unicom.ucloud.eom.common.util;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.sql.Timestamp;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.*;/** * 复制对象属性,并支持扩展类型转换 * * @author 闫帆 */public class BeanUtils {    private static Map<String, Method> methodMap = new HashMap<String, Method>();    static {        Method methods[] = BeanUtils.class.getMethods();        for (Method method : methods) {            methodMap.put(method.getName(), method);        }    }    /**     * 类似BeanUtisl.copyProperties复制对象     * 不同之处可以对同名但不同类型的属性赋值     * 可以配置类型转换方法     * eg:String赋值给Date 需要编写StringToDate方法     *     * @param target 目标对象     * @param source 源对象     * @throws Exception     */    public static void copyProperties(Object source, Object target) {        copyProperties(source, target, true);    }    /**     * 类似BeanUtisl.copyProperties复制对象     * 不同之处可以对同名但不同类型的属性赋值     * 可以配置类型转换方法     * eg:String赋值给Date 需要编写StringToDate方法     *     * @param target       目标对象     * @param source       源对象     * @param nullBeCopied 字段为null的是否复制     * @throws Exception     */    public static void copyProperties(Object source, Object target, Boolean nullBeCopied) {        copyProperties(source, target, null, null, nullBeCopied);    }    /**     * 指定目标对象中需要复制的属性     * 支持属性间类型转换 配置类型转换方法 eg:String赋值给Date 需要编写StringToDate方法     *     * @param target              目标对象     * @param source              源对象     * @param effectiveProperties 需要复制的属性列表     * @throws Exception     */    public static void copyProperties(Object source, Object target, String[] effectiveProperties) {        copyProperties(source, target, effectiveProperties, null, true);    }    /**     * 指定目标对象需要复制的有效属性和无效属性     * 支持属性间类型转换 配置类型转换方法 eg:String赋值给Date 需要编写StringToDate方法     *     * @param target              目标对象     * @param source              源对象     * @param effectiveProperties 需要复制的属性列表     * @param ignoreProperties    不需要复制的属性列表     * @param nullBeCopied        字段为null是否复制     * @throws Exception     */    public static void copyProperties(Object source, Object target, String[] effectiveProperties, String[] ignoreProperties, Boolean nullBeCopied) {        //Field targetFields[]  = destCls.getDeclaredFields();//得到自省对象        BeanInfo beanInfo = null;        try {            beanInfo = Introspector.getBeanInfo(source.getClass());        } catch (IntrospectionException e) {            e.printStackTrace();        }        //得到key为属性名,value为属性对应的PropertyDescriptor的HashMap        PropertyDescriptor sourcePds[] = beanInfo.getPropertyDescriptors();        Map<String, PropertyDescriptor> sourcePdMap = new HashMap<String, PropertyDescriptor>();        for (PropertyDescriptor sourcePd : sourcePds) {            sourcePdMap.put(sourcePd.getName(), sourcePd);        }        List<String> effectiveList = (null == effectiveProperties) ? null : Arrays.asList(effectiveProperties);        List<String> ignoreList = (null == ignoreProperties) ? null : Arrays.asList(ignoreProperties);        try {            PropertyDescriptor targetPds[] = Introspector.getBeanInfo(target.getClass()).getPropertyDescriptors();            //遍历目标对象的所有属性            for (PropertyDescriptor targetPd : targetPds) {                PropertyDescriptor sourcePd = getPropertyDescriptor(sourcePdMap, targetPd.getName());                if (null != targetPd.getWriteMethod() && null != sourcePd                        && (null == effectiveList || effectiveList.contains(targetPd.getName()))                        && (null == ignoreList || !ignoreList.contains(targetPd.getName()))                        ) {                    Method readMethod = sourcePd.getReadMethod();                    if (null == readMethod) {                        continue;                    }                    Object value = readMethod.invoke(source, null);                    //当需要验证并且源对象字段为空时跳过                    if (nullBeCopied == false && null == value) {                        continue;                    }                    Method writeMethod = targetPd.getWriteMethod();                    //如果目标对象和源对象类型相同时直接赋值                    if (sourcePd.getPropertyType().isAssignableFrom(targetPd.getPropertyType())) {                        writeMethod.invoke(target, value);                    } else { //如果目标对象和源对象类型相不同时,调用类型转换方法                        String converMethod = getMethodRuleName(sourcePd.getPropertyType().getName(), targetPd.getPropertyType().getName());                        if (hasConvertMethod(converMethod)) {                            //调用已注册的类型转换方法                            value = getConvertMethod(converMethod).invoke(new BeanUtils(), new Object[]{value});                            writeMethod.invoke(target, value);                        }                    }                }            }        } catch (Exception e) {            System.err.println("复制对象错误");            e.printStackTrace();        }    }    private static String getMethodRuleName(String sourceTypeName, String targetTypeName) {        return sourceTypeName.substring(sourceTypeName.lastIndexOf(".") + 1, sourceTypeName.length()) + "To" + targetTypeName.substring(targetTypeName.lastIndexOf(".") + 1, targetTypeName.length());    }    private static boolean hasConvertMethod(String methodName) {        return methodMap.containsKey(methodName);    }    private static Method getConvertMethod(String methodName) {        return methodMap.get(methodName);    }    private static PropertyDescriptor getPropertyDescriptor(Map<String, PropertyDescriptor> pdMap, String propertyName) {        if (pdMap.containsKey(propertyName)) {            return pdMap.get(propertyName);        }        return null;    }    /**     * 将所有空字符串的属性设为null     *     * @param object     */    public static void setEntryToNull(Object object) {        BeanInfo beanInfo = null;        try {            beanInfo = Introspector.getBeanInfo(object.getClass());        } catch (IntrospectionException e) {            e.printStackTrace();        }        PropertyDescriptor objectPds[] = beanInfo.getPropertyDescriptors();        Object nullObj[] = new Object[1];        nullObj[0] = null;        for (PropertyDescriptor objectPd : objectPds) {            if (objectPd.getPropertyType().isAssignableFrom(String.class) && null != objectPd.getWriteMethod()) {                try {                    String value = (String) objectPd.getReadMethod().invoke(object, null);                    if ("".equals(value)) {                        objectPd.getWriteMethod().invoke(object, nullObj);                    }                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }        public static String IntegerToString(Object obj)    {    return String.valueOf(obj);    }        public static String TimestampToString(Timestamp time)    {    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    return format.format(time);    }////public static Date StringToDate(String obj) {//DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//if(StringUtils.isEmpty(obj)){//return null;//}//try {//return format.parse(obj);//} catch (ParseException e) {////System.err.println(obj+"转换格式错误!");//e.printStackTrace();//return null;//}//}    public static String DateToString(Object obj) {        return obj.toString();    }    public static Date StringToTimestamp(String obj) {        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        return Timestamp.valueOf(obj);    }    /**     * 返回某类的所有方法集合     * key = 大写的方法名     * vale = 方法     *     * @param aClass class对象     */    public static Map<String, Method> getMethodMap(Class aClass) {        Map methodMap = new HashMap();        Method[] methods = aClass.getDeclaredMethods();        for (int i = 0; i < methods.length; i++) {            methodMap.put(methods[i].getName(), methods[i]);        }        return methodMap;    }}