一种c#深拷贝方式完胜java深拷贝(实现上的对比分析)

2019-12-30 13:29:34丽君

单元测试:


@Test
  public void test() throws CloneNotSupportedException {
    Tire tire = new Tire("black",100);
    Car car = new Car("奔驰","white",tire);
    Car car_copy = (Car)deepClone(car);
    System.out.println("car:"+car.hashCode()+" car.tire:"+car.tire.hashCode());
    System.out.println("car_copy:"+car_copy.hashCode()+" car_copy.tire:"+car_copy.tire.hashCode());
    car_copy.color = "blue";
    System.out.println("car_copy:"+car_copy.color+" car:"+car.color);
  }

输出结果:


car:2019524978 car.tire:855703640
car_copy:1407965019 car_copy.tire:545768040
car_copy:blue car:white

从结果集中可以看出是深拷贝是正确的,但是每个类还是需要实现Serializable,好像也不合适吧......

优化一下深拷贝方法:将其换成泛型,这样拷贝出来就不需要强转了(好吧,其实也没比上面的方法好到哪去...)


@SuppressWarnings("unchecked")
  public static <T> T deepClone(T obj)
  {
    T copyObj = null;
    ObjectOutputStream out = null;
    ObjectInputStream in = null;
    try {
      // 序列化
      ByteArrayOutputStream bufferOut = new ByteArrayOutputStream();
      out = new ObjectOutputStream(bufferOut);

      out.writeObject(obj);

      // 反序列化
      ByteArrayInputStream bufferIn = new ByteArrayInputStream(bufferOut.toByteArray());
      in = new ObjectInputStream(bufferIn);
      copyObj = (T)in.readObject();
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e); 
    }finally{
       try{
         if(in != null){
           in.close();
         }
         if(out!=null){
           out.close();
         }
       }catch(IOException e){
         throw new RuntimeException(e);
       }
    }
    return copyObj;
  }

通过序列化与反序列化深拷贝还有更简单的实现方式,就是需要导个包(拷贝的类也必须实现Serializable接口),当然,我已经为你们准备好了 点击->org.apache.commons.lang

深拷贝方法:就一行代码...


public Object deepClone(Object obj){
     return org.apache.commons.lang.SerializationUtils.clone((Serializable)obj);
   }

好了,java的暂时就到这里了,当然对于这两种方式并不是很满意...

-------------------------------------------------

C#深拷贝 反射实现

下面方法是c#的深拷贝,纯反射实现,无需实现任何接口,哦对,需要实体类有个无参的构造方法,简单使用强大,微软大法好啊......有需要用到的同学就拿去用吧,目前经过一个几百W的项目框架中考验,真的强大实用


/// <summary>
    /// 对象拷贝
    /// </summary>
    /// <param name="obj">被复制对象</param>
    /// <returns>新对象</returns>
    private object CopyOjbect(object obj) {
      if (obj == null) {
        return null;
      }
      Object targetDeepCopyObj;
      Type targetType = obj.GetType();
      //值类型 
      if (targetType.IsValueType == true) {
        targetDeepCopyObj = obj;
      }
      //引用类型  
      else {
        targetDeepCopyObj = System.Activator.CreateInstance(targetType);  //创建引用对象  
        System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();

        foreach (System.Reflection.MemberInfo member in memberCollection) {
          //拷贝字段
          if (member.MemberType == System.Reflection.MemberTypes.Field)
          {
            System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
            Object fieldValue = field.GetValue(obj);
            if (fieldValue is ICloneable)
            {
              field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
            }
            else
            {
              field.SetValue(targetDeepCopyObj, CopyOjbect(fieldValue));
            }

          }//拷贝属性
          else if (member.MemberType == System.Reflection.MemberTypes.Property) {
            System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;

            MethodInfo info = myProperty.GetSetMethod(false);
            if (info != null) {
              try {
                object propertyValue = myProperty.GetValue(obj, null);
                if (propertyValue is ICloneable) {
                  myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
                }
                else {
                  myProperty.SetValue(targetDeepCopyObj, CopyOjbect(propertyValue), null);
                }
              }
              catch (System.Exception ex) {

              }
            }
          }
        }
      }
      return targetDeepCopyObj;
    }