java 对象深复制 和 浅复制

深复制与浅复制的概念

1. 什么是浅复制
    浅复制:只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。


2. 什么是深复制
   深复制:就是复制一个完全不同的对象出来,没有任何关联,只是它们的属性值都是相同的,后续对任何一个的修改或其他操作都不会对另外一个有影响!

深复制与浅复制的应用场景

深复制的应用:1、在日志打印时,打印对象的数据时,对敏感信息脱敏

深复制的实现代码

实现思想:
    首先要区分开值复制 和 对象复制,基本数据类型和String类型不需要复制值,直接将值返回,如果为对象 利用newInstance方法 创建一个对象 然后依据是深度复制还是浅复制,再复制对象属性字段,如果属性中有对象属性,再循环递归调用clone方法;
与网上的东西的优势:不用类特殊的实现cloneable 或者 serilizable 接口就可使用,优势在于对于已经成型对象不需要特殊的修改,即可实现复制克隆

/**
 * Copyright 2017 by IPS. Floor 3,Universal Industrial Building, 
 * Tian Yaoqiao Road 1178,Shanghai, P.R. China,200300. All rights reserved.
 *
 * This software is the confidential and proprietary information of IPS
 * ("Confidential Information"). You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with IPS.
 */
package com.xxx.fpms.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/**
 * 
 * @Description: 克隆工具类
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class CloneUtil {
   
   /**
    * 复制对象数据
  * 
    * @param value
    *            原始对象
  * @param level
    *            复制深度。小于0为无限深度,即将深入到最基本类型和Object类级别的数据复制;
  *            大于0则按照其值复制到指定深度的数据,等于0则直接返回对象本身而不进行任何复制行为。
  * @return 返回复制后的对象
  * @throws IllegalAccessException
    * @throws InstantiationException
    * @throws InvocationTargetException
    * @throws NoSuchMethodException
    */
   public static Object clone (Object value, int level) throws IllegalAccessException, InstantiationException, InvocationTargetException,
           NoSuchMethodException {
      if (value == null) {
         return null;
      }
      if (level == 0) {
         return value;
      }
      Class c = value.getClass();
      c.isLocalClass();
      if (isNeedlessClone(c)) {
         return value;
      }
      level--;
      if (value instanceof Collection) {// 复制新的集合
         Collection tmp = (Collection) c.newInstance();
         for (Object v : (Collection) value) {
            tmp.add(clone(v, level));// 深度复制
         }
         value = tmp;
      } else if (c.isArray()) {// 复制新的Array
         // 首先判断是否为基本数据类型
         if (c.equals(int[].class)) {
            int[] old = (int[]) value;
            value = (int[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(short[].class)) {
            short[] old = (short[]) value;
            value = (short[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(char[].class)) {
            char[] old = (char[]) value;
            value = (char[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(float[].class)) {
            float[] old = (float[]) value;
            value = (float[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(double[].class)) {
            double[] old = (double[]) value;
            value = (double[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(long[].class)) {
            long[] old = (long[]) value;
            value = (long[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(boolean[].class)) {
            boolean[] old = (boolean[]) value;
            value = (boolean[]) Arrays.copyOf(old, old.length);
         } else if (c.equals(byte[].class)) {
            byte[] old = (byte[]) value;
            value = (byte[]) Arrays.copyOf(old, old.length);
         } else {
            Object[] old = (Object[]) value;
            Object[] tmp = (Object[]) Arrays.copyOf(old, old.length, old.getClass());
            for (int i = 0; i < old.length; i++) {
               tmp[i] = clone(old[i], level);
            }
            value = tmp;
         }
      } else if (value instanceof Map) {// 复制新的MAP
         Map tmp = (Map) c.newInstance();
         Map org = (Map) value;
         for (Object key : org.keySet()) {
            tmp.put(key, clone(org.get(key), level));// 深度复制
         }
         value = tmp;
      } else {
         Object tmp = null;
         tmp = createObject(value);
         if (tmp == null) {// 无法创建新实例则返回对象本身,没有克隆
            return value;
         }
         Set<Field> fields = new HashSet<Field>();
         while (c != null && !c.equals(Object.class)) {
            fields.addAll(Arrays.asList(c.getDeclaredFields()));
            c = c.getSuperclass();
         }
         for (Field field : fields) {
            if (!Modifier.isFinal(field.getModifiers())) {// 仅复制非final字段
               field.setAccessible(true);
               if ("cdate".equalsIgnoreCase(field.getName())) {
                  continue;
               }
               field.set(tmp, clone(val, level));// 深度复制
       }
         }
         value = tmp;
      }
      return value;
   }

   /**
    * 浅表复制对象
    * 
    * @param value
    *            原始对象
    * @return 复制后的对象,只复制一层
    * @throws IllegalAccessException
    * @throws InstantiationException
    * @throws InvocationTargetException
    * @throws NoSuchMethodException
    */
   public static Object clone (Object value) {
      try {
         return clone(value, 1);
      } catch (Exception e) {
         logger.error(e.getMessage(), e);
         return value;
      }
   }

   /**
    * 深度复制对象
    * 
    * @param value
    *            原始对象
    * @return 复制后的对象
    * @throws IllegalAccessException
    * @throws InstantiationException
    * @throws InvocationTargetException
    * @throws NoSuchMethodException
    */
   public static Object deepClone (Object value) {
      try {
         return clone(value, -1);
      } catch (Exception e) {
         logger.error(e.getMessage(), e);
         return value;
      }
   }

   /**
    * 无需进行复制的特殊类型数组
    */
   static Class[] needlessCloneClasses = new Class[] { String.class, Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class,
           Float.class, Double.class, Void.class, Object.class, Class.class };

   /**
    * 判断该类型对象是否无需复制
    * 
    * @param c
    *            指定类型
    * @return 如果不需要复制则返回真,否则返回假
    */
   private static boolean isNeedlessClone (Class c) {
      if (c.isPrimitive()) {// 基本类型
         return true;
      }
      for (Class tmp : needlessCloneClasses) {// 是否在无需复制类型数组里
         if (c.equals(tmp)) {
            return true;
         }
      }
      return false;
   }

   /**
    * 尝试创建新对象
    * 
    * @param c
    *            原始对象
    * @return 新的对象
    * @throws IllegalAccessException
    */
   private static Object createObject (Object value) throws IllegalAccessException {
      try {
         return value.getClass().newInstance();
      } catch (InstantiationException e) {
         return null;
      } catch (IllegalAccessException e) {
         throw e;
      }
   }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值