Java对象之间的深度复制拷贝



/*
 * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

/**
 * {@code RuntimeException} is the superclass of those
 * exceptions that can be thrown during the normal operation of the
 * Java Virtual Machine.
 *
 * 

{@code RuntimeException} and its subclasses are unchecked * exceptions. Unchecked exceptions do not need to be * declared in a method or constructor's {@code throws} clause if they * can be thrown by the execution of the method or constructor and * propagate outside the method or constructor boundary. * * @author Frank Yellin * @jls 11.2 Compile-Time Checking of Exceptions * @since JDK1.0 */ public class RuntimeException extends Exception { static final long serialVersionUID = -7034897190745766939L; /** Constructs a new runtime exception with {@code null} as its * detail message. The cause is not initialized, and may subsequently be * initialized by a call to {@link #initCause}. */ public RuntimeException() { super(); } /** Constructs a new runtime exception with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a * call to {@link #initCause}. * * @param message the detail message. The detail message is saved for * later retrieval by the {@link #getMessage()} method. */ public RuntimeException(String message) { super(message); } /** * Constructs a new runtime exception with the specified detail message and * cause.

Note that the detail message associated with * {@code cause} is not automatically incorporated in * this runtime exception's detail message. * * @param message the detail message (which is saved for later retrieval * by the {@link #getMessage()} method). * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.4 */ public RuntimeException(String message, Throwable cause) { super(message, cause); } /** Constructs a new runtime exception with the specified cause and a * detail message of (cause==null ? null : cause.toString()) * (which typically contains the class and detail message of * cause). This constructor is useful for runtime exceptions * that are little more than wrappers for other throwables. * * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.4 */ public RuntimeException(Throwable cause) { super(cause); } /** * Constructs a new runtime exception with the specified detail * message, cause, suppression enabled or disabled, and writable * stack trace enabled or disabled. * * @param message the detail message. * @param cause the cause. (A {@code null} value is permitted, * and indicates that the cause is nonexistent or unknown.) * @param enableSuppression whether or not suppression is enabled * or disabled * @param writableStackTrace whether or not the stack trace should * be writable * * @since 1.7 */ protected RuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }

  package com.todaytech.pwp.core.exception;


  public class SysException
    extends RuntimeException
  {
    public SysException() {}




    public SysException(String message)
    {
      super(message);
    }





    public SysException(String message, Throwable cause)
    {
      super(message, cause);
    }





    public SysException(Throwable cause)
    {
      super(cause);
    }
  }


 package com.todaytech.pwp.core.util.beanutils;

 import com.todaytech.pwp.core.exception.SysException;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.beanutils.BeanUtils;
 import org.apache.commons.beanutils.ConvertUtils;
 import org.apache.commons.beanutils.DynaBean;
 import org.apache.commons.beanutils.DynaClass;
 import org.apache.commons.beanutils.DynaProperty;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.beanutils.converters.BigDecimalConverter;





 public final class ReflectUtil
 {
   private ReflectUtil() {}

   public static String getFieldByName(Object orig, String fieldName, boolean pbIgnoreCase)
   {
     Field[] origFields = getDeclaredFieldsForClass(orig.getClass());
     String fieldNameToFind = fieldName;
     if (pbIgnoreCase) {
       fieldNameToFind = fieldName.toUpperCase();
     }
     Object objValue = null;

     for (int i = 0; i < origFields.length; i++) {
       Field origField = origFields[i];
       String name = origField.getName();
       if (pbIgnoreCase) {
         name = name.toUpperCase();
       }
       if (name.equals(fieldNameToFind)) {
         origField.setAccessible(true);
         try {
           objValue = origField.get(orig);
         } catch (IllegalAccessException e) {
           throw new SysException(e);
         }
         origField.setAccessible(false);
         break;
       }
     }
     if (objValue != null) {
       return ConvertUtils.convert(objValue);
     }
     return null;
   }









   public static void setFieldByName(Object orig, String fieldName, String value, boolean pbIgnoreCase)
   {
     Field[] origFields = getDeclaredFieldsForClass(orig.getClass());
     String fieldNameToFind = fieldName;
     if (pbIgnoreCase) {
       fieldNameToFind = fieldName.toUpperCase();
     }
     boolean found = false;

     for (int i = 0; i < origFields.length; i++) {
       Field origField = origFields[i];
       String name = origField.getName();
       if (pbIgnoreCase) {
         name = name.toUpperCase();
       }
       if (name.equals(fieldNameToFind)) {
         origField.setAccessible(true);
         try {
           origField.set(orig, value);
         } catch (IllegalAccessException e) {
           throw new SysException(e);
         }
         origField.setAccessible(false);
         found = true;
         break;
       }
     }
     if (!found) {
       throw new IllegalArgumentException("Field not found. fieldName ='" + fieldName + "'");
     }
   }








   public static Object invokeMethod(Object owner, String methodName, Object... args)
   {
     Class ownerClass = owner.getClass();
     Class[] argsClass = new Class[args.length];
     int i = 0; for (int j = args.length; i < j; i++) {
       argsClass[i] = args[i].getClass();
     }
     Method method = null;
     try {
       method = ownerClass.getMethod(methodName, argsClass);
       return method.invoke(owner, args);
     } catch (NoSuchMethodException e) {
       throw new SysException(e);
     } catch (InvocationTargetException e) {
       throw new SysException(e);
     } catch (IllegalAccessException e) {
       throw new SysException(e);
     }
   }









   public static Object invokeStaticMethod(String className, String methodName, Object... args)
   {
     Class ownerClass = null;
     try {
       ownerClass = Class.forName(className);
       Class[] argsClass = new Class[args.length];
       int i = 0; for (int j = args.length; i < j; i++) {
         argsClass[i] = args[i].getClass();
       }
       Method method = ownerClass.getMethod(methodName, argsClass);
       return method.invoke(null, args);
     } catch (ClassNotFoundException e) {
       throw new SysException(e);
     } catch (InvocationTargetException e) {
       throw new SysException(e);
     } catch (NoSuchMethodException e) {
       throw new SysException(e);
     } catch (IllegalAccessException e) {
       throw new SysException(e);
     }
   }








   public static Object newInstance(String className, Object... args)
   {
     Class newoneClass = null;
     try {
       newoneClass = Class.forName(className);
       Class[] argsClass = new Class[args.length];
       int i = 0; for (int j = args.length; i < j; i++) {
         argsClass[i] = args[i].getClass();
       }
       Constructor cons = newoneClass.getConstructor(argsClass);
       return cons.newInstance(args);
     } catch (ClassNotFoundException e) {
       throw new SysException(e);
     } catch (InvocationTargetException e) {
       throw new SysException(e);
     } catch (NoSuchMethodException e) {
       throw new SysException(e);
     } catch (InstantiationException e) {
       throw new SysException(e);
     } catch (IllegalAccessException e) {
       throw new SysException(e);
     }
   }







   public static void copyNotNullProperties(Object objFrom, Object objTo)
   {
     copyAllPropertiesByName(objFrom, objTo, false);
   }






   public static void copyAllProperties(Object objFrom, Object objTo)
   {
     ConvertUtils.register(new DateConverter(), java.util.Date.class);
     ConvertUtils.register(new DateConverter(), java.sql.Date.class);
     ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
     copyAllPropertiesByName(objFrom, objTo, true);
   }







   private static void copyAllPropertiesByName(Object objFrom, Object objTo, boolean bIncludeNull)
   {
     if (bIncludeNull) {
       try {
         BeanUtils.copyProperties(objTo, objFrom);
       } catch (IllegalAccessException e) {
         throw new SysException(e);
       } catch (InvocationTargetException e) {
         throw new SysException(e);
       }
     } else {
       copyProperties(objTo, objFrom, bIncludeNull);
     }
   }







   private static void copyProperties(Object dest, Object orig, boolean bIncludeNull)
   {
     if (dest == null) {
       throw new IllegalArgumentException("No destination bean specified");
     }
     if (orig == null) {
       throw new IllegalArgumentException("No origin bean specified");
     }

     if ((orig instanceof DynaBean)) {
       copyDynaBean(dest, (DynaBean)orig, bIncludeNull);
     } else if ((orig instanceof Map)) {
       copyBeanMap(dest, (Map)orig, bIncludeNull);
     } else {
       copyBeanArray(dest, orig, bIncludeNull);
     }
   }

   private static void copyBeanArray(Object dest, Object orig, boolean bIncludeNull) {
     PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(orig);
     for (int i = 0; i < origDescriptors.length; i++) {
       String name = origDescriptors[i].getName();
       if (!"class".equals(name))
       {

         if ((PropertyUtils.isReadable(orig, name)) && (PropertyUtils.isWriteable(dest, name)))
           try {
             Object value = PropertyUtils.getSimpleProperty(orig, name);
             if ((bIncludeNull) || (value != null)) {
               BeanUtils.copyProperty(dest, name, value);
             }
           } catch (NoSuchMethodException ex) {
             throw new SysException(ex);
           } catch (InvocationTargetException e) {
             throw new SysException(e);
           } catch (IllegalAccessException e) {
             throw new SysException(e);
           }
       }
     }
   }

   private static void copyBeanMap(Object dest, Map orig, boolean bIncludeNull) {
     Iterator names = orig.keySet().iterator();
     while (names.hasNext()) {
       String name = (String)names.next();
       if (PropertyUtils.isWriteable(dest, name)) {
         Object value = orig.get(name);
         if ((bIncludeNull) || (value != null)) {
           try {
             BeanUtils.copyProperty(dest, name, value);
           } catch (IllegalAccessException e) {
             throw new SysException(e);
           } catch (InvocationTargetException e) {
             throw new SysException(e);
           }
         }
       }
     }
   }

   private static void copyDynaBean(Object dest, DynaBean orig, boolean bIncludeNull) {
     DynaProperty[] origDescriptors = orig.getDynaClass().getDynaProperties();
     for (int i = 0; i < origDescriptors.length; i++) {
       String name = origDescriptors[i].getName();
       if (PropertyUtils.isWriteable(dest, name)) {
         Object value = orig.get(name);
         if ((bIncludeNull) || (value != null)) {
           try {
             BeanUtils.copyProperty(dest, name, value);
           } catch (IllegalAccessException e) {
             throw new SysException(e);
           } catch (InvocationTargetException e) {
             throw new SysException(e);
           }
         }
       }
     }
   }








   public static void setPropertyByName(Object objTo, String sFieldName, Object value, boolean bIgnoreCase)
   {
     if (bIgnoreCase) {
       sFieldName = findPropertyName(objTo.getClass(), sFieldName);
     }
     try {
       BeanUtils.copyProperty(objTo, sFieldName, value);
     } catch (IllegalAccessException e) {
       throw new SysException(e);
     } catch (InvocationTargetException e) {
       throw new SysException(e);
     }
   }







   private static String findPropertyName(Class objClz, String sFieldName)
   {
     Field[] fields = getDeclaredFields(objClz);
     String sToRet = null;
     for (int i = 0; i < fields.length; i++) {
       Field field = fields[i];
       String fieldName = field.getName();
       if (fieldName.equalsIgnoreCase(sFieldName)) {
         sToRet = fieldName;
         break;
       }
     }
     return sToRet;
   }






   private static Field[] getDeclaredFields(Class objClz)
   {
     ArrayList fields = new ArrayList();
     Class curClz = objClz;
     Collections.addAll(fields, curClz.getDeclaredFields());
     while (curClz.getSuperclass() != Object.class) {
       curClz = curClz.getSuperclass();
       Collections.addAll(fields, curClz.getDeclaredFields());
     }
     return (Field[])fields.toArray(new Field[fields.size()]);
   }






   private static Field[] getDeclaredFieldsForClass(Class clz)
   {
     if (clz == Object.class) {
       return new Field[0];
     }
     ArrayList fieldlist = new ArrayList();
     fieldlist.addAll(Arrays.asList(clz.getDeclaredFields()));
     Field[] fieldsOfSuperClz = getDeclaredFieldsForClass(clz.getSuperclass());
     if (fieldsOfSuperClz != null) {
       fieldlist.addAll(Arrays.asList(fieldsOfSuperClz));
     }
     return (Field[])fieldlist.toArray(new Field[0]);
   }









   private static Map describeByFields(Object obj, boolean bGetSuperClassToo)
   {
     if (obj == null) {
       throw new IllegalArgumentException("No obj specified");
     }
     Class classToView = obj.getClass();
     return describeByFields(obj, classToView, bGetSuperClassToo);
   }







   private static Map describeByFields(Object obj, Class pClassToView, boolean bGetSuperClassToo)
   {
     Map toReturn = new HashMap();
     if (bGetSuperClassToo) {
       Class superclz = pClassToView.getSuperclass();
       if (superclz != Object.class) {
         toReturn.putAll(describeByFields(obj, superclz, bGetSuperClassToo));
       }
     }
     Field[] origFields = pClassToView.getDeclaredFields();
     for (Field origField : origFields) {
       String name = origField.getName();
       origField.setAccessible(true);
       try {
         toReturn.put(name, origField.get(obj));
       } catch (IllegalAccessException e) {
         throw new SysException(e);
       }
     }
     return toReturn;
   }









   public static  Class getGenericTypeArgument(Class clazz)
   {
     return getGenericTypeArgument(clazz, 0);
   }











   public static Class getGenericTypeArgument(Class clazz, int index)
   {
     Type genType = clazz.getGenericSuperclass();

     if (!(genType instanceof ParameterizedType))
     {
       return Object.class;
     }

     Type[] params = ((ParameterizedType)genType).getActualTypeArguments();

     if ((index >= params.length) || (index < 0))
     {

       return Object.class;
     }
     if (!(params[index] instanceof Class))
     {
       return Object.class;
     }

     return (Class)params[index];
   }
 }

你可能感兴趣的:(Java对象之间的深度复制拷贝)