亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一種c#深拷貝方式完勝java深拷貝(實(shí)現(xiàn)上的對(duì)比分析)

 更新時(shí)間:2016年07月06日 10:22:29   投稿:jingxian  
下面小編就為大家?guī)?lái)一篇一種c#深拷貝方式完勝java深拷貝(實(shí)現(xiàn)上的對(duì)比分析)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

樓主是一名asp.net攻城獅,最近經(jīng)常跑java組客串幫忙開(kāi)發(fā),所以最近對(duì)java的一些基礎(chǔ)知識(shí)特別上心。卻遇到需要將一個(gè)對(duì)象深拷貝出來(lái)做其他事情,而原對(duì)象保持原有狀態(tài)的情況。(實(shí)在是不想自己new一個(gè)出來(lái),然后對(duì)著一堆字段賦值......好吧,再此之前我沒(méi)有關(guān)心是否項(xiàng)目框架有深拷貝的方法),然后就想著用反射實(shí)現(xiàn)吧....接下來(lái)

是我自己的原因,還是真的不存在這樣的純用反射實(shí)現(xiàn)的深拷貝方式....(c#是有純反射實(shí)現(xiàn)的)

但也不能算自己白忙活吧,也找到了其他實(shí)現(xiàn)深拷貝的方式(但是每種方式我都覺(jué)得并不是太合理,也許是因?yàn)閏#的方式帶入了吧,最后貼出c#版本純反射實(shí)現(xiàn)深拷貝的代碼)

方式一:實(shí)現(xiàn)Cloneable接口,重寫clone方法

實(shí)體類:一個(gè)輪胎類,一個(gè)車輛類,車輛中包含輪胎

/**輪胎類**/
public class Tire implements Cloneable {
  public String color;
  public int radius;
  public Tire(){}
  public Tire(String color, int radius) {
    this.color = color;
    this.radius = radius;
  }

  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
/**車輛類**/
public class Car implements Cloneable{
  public String name;
  public String color;
  public Tire tire;
  public Car() {}
  public Car(String name, String color, Tire tire) {
    this.name = name;
    this.color = color;
    this.tire = tire;
  }
  public void whistle(){
    System.out.println("汽車"+this.name+" 鳴笛...");
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getColor() {
    return color;
  }
  public void setColor(String color) {
    this.color = color;
  }
  public Tire getTire() {
    return tire;
  }
  public void setTire(Tire tire) {
    this.tire = tire;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}

@Test
  public void test() throws CloneNotSupportedException {
    Tire tire = new Tire("black",100);
    Car car = new Car("奔馳","white",tire);
    Car car_copy = (Car)car.clone();
    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);
  }

輸出結(jié)果:

car:1223737555 car.tire:906199566
car_copy:542081238 car_copy.tire:906199566
car_copy:blue car:white

從結(jié)果可以的之,car與car_copy的內(nèi)存地址并不一致,但car.tire與car_copy.tire的內(nèi)存地址卻是一致的,說(shuō)明“奔馳”車確實(shí)又造出了一輛,但卻公用同一幅輪胎(這種情形....哈哈哈),好吧,也就是只復(fù)制了tire的引用,這可以說(shuō)是深拷貝的不徹底 (hashCode()的值可以當(dāng)作是內(nèi)存地址來(lái)理解),那么要怎樣才能徹底,真正的深拷貝?

修改Car類中的clone方法:

@Override
  protected Object clone() throws CloneNotSupportedException {
    Car car = (Car)super.clone();
    car.tire = (Tire)car.tire.clone();
    return car;
  }

輸出結(jié)果:

car:1223737555 car.tire:906199566
car_copy:542081238 car_copy.tire:1133736492
car_copy:blue car:white

這樣最終實(shí)現(xiàn)了,但這種方式用到項(xiàng)目中并不是很合適吧,每個(gè)需要深拷貝的類,都要實(shí)現(xiàn)Cloneable接口,并覆蓋其clone方法,遇到引用其他類時(shí)候更是需要修改clone方法,要是引用其他類,其他類再引用其他類呢?這不好吧......

方式二:通過(guò)序列化與反序列化實(shí)現(xiàn)(實(shí)現(xiàn)Serializable接口)

實(shí)體類:與第一種方式類似,換成實(shí)現(xiàn)Serializable接口,去掉clone方法

/**輪胎類**/
@SuppressWarnings("serial")
public class Tire implements java.io.Serializable {
  public String color;
  public int radius;
  public Tire(){}
  public Tire(String color, int radius) {
    this.color = color;
    this.radius = radius;
  }
}
/**車輛類**/
@SuppressWarnings("serial")
public class Car implements java.io.Serializable{
  public String name;
  public String color;
  public Tire tire;
  public Car() {}
  public Car(String name, String color, Tire tire) {
    this.name = name;
    this.color = color;
    this.tire = tire;
  }
  public void whistle(){
    System.out.println("汽車"+this.name+" 鳴笛...");
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getColor() {
    return color;
  }
  public void setColor(String color) {
    this.color = color;
  }
  public Tire getTire() {
    return tire;
  }
  public void setTire(Tire tire) {
    this.tire = tire;
  }
}

深拷貝方法:

@SuppressWarnings("unchecked")
  public static Object deepClone(Object obj)
  {
    Object 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 = 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;
  }

單元測(cè)試:

@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);
  }

輸出結(jié)果:

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

從結(jié)果集中可以看出是深拷貝是正確的,但是每個(gè)類還是需要實(shí)現(xiàn)Serializable,好像也不合適吧......

優(yōu)化一下深拷貝方法:將其換成泛型,這樣拷貝出來(lái)就不需要強(qiáng)轉(zhuǎn)了(好吧,其實(shí)也沒(méi)比上面的方法好到哪去...)

@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;
  }

通過(guò)序列化與反序列化深拷貝還有更簡(jiǎn)單的實(shí)現(xiàn)方式,就是需要導(dǎo)個(gè)包(拷貝的類也必須實(shí)現(xiàn)Serializable接口),當(dāng)然,我已經(jīng)為你們準(zhǔn)備好了 點(diǎn)擊->org.apache.commons.lang

深拷貝方法:就一行代碼...

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

好了,java的暫時(shí)就到這里了,當(dāng)然對(duì)于這兩種方式并不是很滿意...

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

C#深拷貝 反射實(shí)現(xiàn)

下面方法是c#的深拷貝,純反射實(shí)現(xiàn),無(wú)需實(shí)現(xiàn)任何接口,哦對(duì),需要實(shí)體類有個(gè)無(wú)參的構(gòu)造方法,簡(jiǎn)單使用強(qiáng)大,微軟大法好啊......有需要用到的同學(xué)就拿去用吧,目前經(jīng)過(guò)一個(gè)幾百W的項(xiàng)目框架中考驗(yàn),真的強(qiáng)大實(shí)用

/// <summary>
    /// 對(duì)象拷貝
    /// </summary>
    /// <param name="obj">被復(fù)制對(duì)象</param>
    /// <returns>新對(duì)象</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);  //創(chuàng)建引用對(duì)象  
        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;
    }

以上這篇一種c#深拷貝方式完勝java深拷貝(實(shí)現(xiàn)上的對(duì)比分析)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

單元測(cè)試:

相關(guān)文章

  • C#如何取硬件標(biāo)志

    C#如何取硬件標(biāo)志

    C#如何取硬件標(biāo)志...
    2007-03-03
  • C# 使用AE獲取feature的屬性及字段操作

    C# 使用AE獲取feature的屬性及字段操作

    這篇文章主要介紹了C# 使用AE獲取feature的屬性及字段操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • DevExpress實(shí)現(xiàn)GridControl單元格編輯驗(yàn)證的方法

    DevExpress實(shí)現(xiàn)GridControl單元格編輯驗(yàn)證的方法

    這篇文章主要介紹了DevExpress實(shí)現(xiàn)GridControl單元格編輯驗(yàn)證的方法,很實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • C# WinForm程序完全退出的問(wèn)題解決

    C# WinForm程序完全退出的問(wèn)題解決

    C# WinForm程序完全退出的問(wèn)題解決,需要的朋友可以參考一下
    2013-05-05
  • C#基于Windows服務(wù)的聊天程序(1)

    C#基于Windows服務(wù)的聊天程序(1)

    這篇文章主要為大家詳細(xì)介紹了C#基于Windows服務(wù)的聊天程序的第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • C#集合之棧的用法

    C#集合之棧的用法

    這篇文章介紹了C#集合之棧的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#9.0 新特性簡(jiǎn)介

    C#9.0 新特性簡(jiǎn)介

    這篇文章主要介紹了C#9.0 新特性簡(jiǎn)介,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋小游戲

    C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下<BR>
    2021-11-11
  • 使用xmltextreader對(duì)象讀取xml文檔示例

    使用xmltextreader對(duì)象讀取xml文檔示例

    這篇文章主要介紹了使用xmltextreader對(duì)象讀取xml文檔的示例,需要的朋友可以參考下
    2014-02-02
  • c# 字符串操作總結(jié)

    c# 字符串操作總結(jié)

    這篇文章主要介紹了c# 字符串操作的相關(guān)知識(shí),文中講解的非常詳細(xì),代碼幫助大家更好的學(xué)習(xí),感興趣的朋友可以參考下
    2020-06-06

最新評(píng)論