亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

實例分析java對象中淺克隆和深克隆

2024-07-14 08:42:30
字體:
來源:轉載
供稿:網友

引言:

在Object基類中,有一個方法叫clone,產生一個前期對象的克隆,克隆對象是原對象的拷貝,由于引用類型的存在,有深克隆和淺克隆之分,若克隆對象中存在引用類型的屬性,深克隆會將此屬性完全拷貝一份,而淺克隆僅僅是拷貝一份此屬性的引用。首先看一下容易犯的幾個小問題

clone方法是Object類的,并不是Cloneable接口的,Cloneable只是一個標記接口,標記接口是用用戶標記實現該接口的類具有某種該接口標記的功能,常見的標記接口有三個:Serializable、Cloneable、RandomAccess,沒有實現Cloneable接口,那么調用clone方法就會爆出CloneNotSupportedException異常。

Object類中的clone方法是protected修飾的,這就表明我們在子類中不重寫此方法,就在子類外無法訪問,因為這個protected權限是僅僅能在Object所在的包和子類能訪問的,這也驗證了子類重寫父類方法權限修飾符可以變大但不能變小的說法。

protected native Object clone() throws CloneNotSupportedException;

重寫clone方法,內部僅僅是調用了父類的clone方法,其實是為了擴大訪問權限,當然你可以把protected改為public,以后再繼承就不用重寫了。當然只是淺克隆的clone函數,深克隆就需要修改了。

@Override  protected Object clone() throws CloneNotSupportedException {     return super.clone();}

屬性是String的情況,String也是一個類,那String引用類型嗎?String的表現有的像基本類型,歸根到底就是因為String不可改變,克隆之后倆個引用指向同一個String,但當修改其中的一個,改的不是String的值,卻是新生成一個字符串,讓被修改的引用指向新的字符串。外表看起來就像基本類型一樣。

淺克?。?/strong>

淺克隆就是引用類型的屬性無法完全復制,類User中包含成績屬性Mark,Mark是由Chinese和math等等組成的,淺克隆失敗的例子

class Mark{  private int chinese;  private int math;  public Mark(int chinese, int math) {    this.chinese = chinese;    this.math = math;  }   public void setChinese(int chinese) {    this.chinese = chinese;  }   public void setMath(int math) {    this.math = math;  }   @Override  public String toString() {    return "Mark{" +        "chinese=" + chinese +        ", math=" + math +        '}';  }}public class User implements Cloneable{  private String name;  private int age;  private Mark mark;   public User(String name, int age,Mark mark) {    this.name = name;    this.age = age;    this.mark = mark;  }   @Override  public String toString() {    return "User{" +        "name='" + name + '/'' +        ", age=" + age +        ", mark=" + mark +        '}';  }   @Override  protected Object clone() throws CloneNotSupportedException {    return super.clone();  }   public static void main(String[] args) throws CloneNotSupportedException {    Mark mark = new Mark(100,99);    User user = new User("user",22,mark);    User userClone = (User) user.clone();    System.out.println("原user:"+user);    System.out.println("克隆的user:"+userClone);    //修改引用類型的mark屬性    user.mark.setMath(60);    System.out.println("修改后的原user:"+user);    System.out.println("修改后的克隆user:"+userClone);  }}

輸出結果為:   

原user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
克隆的user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name='user', age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name='user', age=22, mark=Mark{chinese=100, math=60}}

很清楚的看到user的mark更改后,被克隆的user也修改了。而要想不被影響,就需要深克隆了。

深克?。?/strong>

方式一:clone函數的嵌套調用

既然引用類型無法被完全克隆,那將引用類型也實現Cloneable接口重寫clone方法,在User類中的clone方法調用屬性的克隆方法,也就是方法的嵌套調用

class Mark implements Cloneable{  private int chinese;  private int math;  public Mark(int chinese, int math) {    this.chinese = chinese;    this.math = math;  }  public void setChinese(int chinese) {    this.chinese = chinese;  }  public void setMath(int math) {    this.math = math;  }  @Override  protected Object clone() throws CloneNotSupportedException {    return super.clone();  }  @Override  public String toString() {    return "Mark{" +        "chinese=" + chinese +        ", math=" + math +        '}';  }}public class User implements Cloneable{  private String name;  private int age;  private Mark mark;   public User(String name, int age,Mark mark) {    this.name = name;    this.age = age;    this.mark = mark;  }   @Override  public String toString() {    return "User{" +        "name='" + name + '/'' +        ", age=" + age +        ", mark=" + mark +        '}';  }   @Override  protected Object clone() throws CloneNotSupportedException {    User user = (User) super.clone();    user.mark = (Mark) this.mark.clone();    return user;  }   public static void main(String[] args) throws CloneNotSupportedException {    Mark mark = new Mark(100,99);    User user = new User("user",22,mark);    User userClone = (User) user.clone();    System.out.println("原user:"+user);    System.out.println("克隆的user:"+userClone);    //修改引用類型的mark屬性    user.mark.setMath(60);    System.out.println("修改后的原user:"+user);    System.out.println("修改后的克隆user:"+userClone);  }}

輸出結果為: 

原user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
克隆的user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name='user', age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}

方式二:序列化

上一種方法已經足夠滿足我們的需要,但是如果類之間的關系很多,或者是有的屬性是數組呢,數組可無法實現Cloneable接口(我們可以在clone方法中手動復制數組),但是每次都得手寫clone方法,很麻煩,而序列化方式只需要給每個類都實現一個Serializable接口,也是標記接口,最后同序列化和反序列化操作達到克隆的目的(包括數組的復制)。序列化和反序列化的知識請參照下一篇

import java.io.*;class Mark implements Serializable {  private int chinese;  private int math;  public Mark(int chinese, int math) {    this.chinese = chinese;    this.math = math;}  public void setChinese(int chinese) {    this.chinese = chinese;  }  public void setMath(int math) {    this.math = math;  }  @Override  public String toString() {    return "Mark{" +        "chinese=" + chinese +        ", math=" + math +        '}';  }}public class User implements Serializable{  private String name;  private int age;  private Mark mark;   public User(String name, int age,Mark mark) {    this.name = name;    this.age = age;    this.mark = mark;  }   @Override  public String toString() {    return "User{" +        "name='" + name + '/'' +        ", age=" + age +        ", mark=" + mark +        '}';  }  public static void main(String[] args) throws IOException, ClassNotFoundException {    Mark mark = new Mark(100,99);    User user = new User("user",22,mark);     ByteArrayOutputStream bo = new ByteArrayOutputStream();    ObjectOutputStream oo = new ObjectOutputStream(bo);    oo.writeObject(user);//序列化    ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());    ObjectInputStream oi = new ObjectInputStream(bi);    User userClone = (User) oi.readObject();//反序列化     System.out.println("原user:"+user);    System.out.println("克隆的user:"+userClone);    user.mark.setMath(59);    System.out.println("修改后的原user:"+user);    System.out.println("修改后的克隆user:"+userClone);  }}

輸出結果:

原user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
克隆的user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name='user', age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name='user', age=22, mark=Mark{chinese=100, math=99}}

帶數組屬性的克隆

import java.io.*;import java.util.Arrays; public class User implements Serializable{  private String name;  private int age;  private int[] arr;   public User(String name, int age, int[] arr) {    this.name = name;    this.age = age;    this.arr = arr;  }  @Override  public String toString() {    return "User{" +        "name='" + name + '/'' +        ", age=" + age +        ", arr=" + Arrays.toString(arr) +        '}';  }  public static void main(String[] args) throws IOException, ClassNotFoundException {    int[] arr = {1,2,3,4,5,6};    User user = new User("user",22,arr);     ByteArrayOutputStream bo = new ByteArrayOutputStream();    ObjectOutputStream oo = new ObjectOutputStream(bo);    oo.writeObject(user);//序列化    ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());    ObjectInputStream oi = new ObjectInputStream(bi);    User userClone = (User) oi.readObject();//反序列化     System.out.println("原user:"+user);    System.out.println("克隆的user:"+userClone);    user.arr[1] = 9;    System.out.println("修改后的原user:"+user);    System.out.println("修改后的克隆user:"+userClone);  }}


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品久久久久久牛牛| 91精品视频网站| 精品久久香蕉国产线看观看亚洲| 亚洲欧美一区二区三区四区| 久久亚洲国产精品成人av秋霞| 视频直播国产精品| 综合av色偷偷网| 欧美成人精品三级在线观看| 久久成年人视频| 欧美日本亚洲视频| 日韩av在线免费观看| 色999日韩欧美国产| 亚洲综合在线中文字幕| 国产视频精品一区二区三区| 亲子乱一区二区三区电影| 精品国产成人av| 国产精品免费久久久久久| 国产成人涩涩涩视频在线观看| 国产精品一区二区av影院萌芽| 亚洲少妇中文在线| 国产噜噜噜噜久久久久久久久| 一本色道久久综合亚洲精品小说| **欧美日韩vr在线| 精品久久久久久久久中文字幕| 成人免费淫片aa视频免费| 欧美日韩美女在线| 欧美另类极品videosbestfree| 国产精品永久免费观看| 亚洲精品成人免费| 亚洲老板91色精品久久| 久久精品亚洲精品| 国产精品视频白浆免费视频| 在线国产精品播放| 亚洲女人天堂成人av在线| 91精品视频免费观看| 欧美成人黑人xx视频免费观看| 欧美精品成人91久久久久久久| 久久国产精品首页| 国产欧美在线播放| 日韩有码片在线观看| 欧美一区第一页| 欧美日韩国产一区中文午夜| 亚洲男人天堂2019| 色妞久久福利网| 97成人超碰免| 91精品国产91久久久久福利| 一区二区三区在线播放欧美| 国产日韩欧美影视| 亚洲bt欧美bt日本bt| 日韩中文字幕久久| 久久影视电视剧免费网站| 国产色综合天天综合网| 日韩电影免费在线观看中文字幕| 黑人巨大精品欧美一区免费视频| 国产精品99久久久久久久久久久久| 久久电影一区二区| 成人a在线观看| 欧美高清性猛交| 国产精品美女www爽爽爽视频| 国产成人aa精品一区在线播放| 国产精品久久久久久久久久久不卡| 久久精品99久久香蕉国产色戒| 在线免费看av不卡| 国产精品∨欧美精品v日韩精品| 欧美激情一区二区久久久| 97视频色精品| 亚洲精品乱码久久久久久按摩观| www.亚洲一区| 国内精品久久久久久影视8| 欧美激情综合色综合啪啪五月| 亚洲欧美中文日韩v在线观看| 国产精品久久久久久久午夜| 亚洲一级免费视频| 91啪国产在线| 国产成人精品在线观看| 97在线精品国自产拍中文| 日韩在线视频观看正片免费网站| 91牛牛免费视频| 91最新在线免费观看| 97超级碰碰碰| 九九热这里只有在线精品视| 色视频www在线播放国产成人| 亚洲日韩中文字幕在线播放| 国内精品小视频| 中文字幕亚洲无线码在线一区| 国产综合在线视频| 最近2019中文字幕在线高清| 日韩美女在线观看一区| 国产精品视频1区| 亚洲二区在线播放视频| 久久综合国产精品台湾中文娱乐网| 国产一区二区在线免费视频| 久久成人综合视频| 大胆欧美人体视频| 欧美精品videos| 国产精品麻豆va在线播放| 伊人青青综合网站| 欧美亚洲国产视频小说| 日韩欧美国产一区二区| 欧美亚洲国产视频小说| 国产成人avxxxxx在线看| 91在线高清视频| 久久精品国产亚洲精品| 欧美成在线观看| 中文字幕自拍vr一区二区三区| 国产97免费视| 日韩欧美在线网址| 色妞久久福利网| 国产91免费观看| 日韩av免费网站| 国产精品av免费在线观看| 欧美视频一二三| 久久久久国产精品免费网站| 欧美日韩免费观看中文| 久久影院在线观看| 精品国产乱码久久久久久天美| 日韩欧美在线网址| 精品亚洲国产成av人片传媒| 日韩在线不卡视频| 欧美视频一区二区三区…| 国产在线播放不卡| 成人美女av在线直播| 亚洲成年人在线播放| 亚洲国产欧美一区二区丝袜黑人| 欧美日韩精品在线观看| 欧美成人免费在线视频| 国产美女高潮久久白浆| 亚洲人在线观看| 正在播放欧美一区| 欧美日韩在线第一页| 亚洲综合中文字幕在线| 欧美精品手机在线| 色噜噜久久综合伊人一本| 欧美高清第一页| 欧美日韩激情视频8区| 久久久在线免费观看| 久久综合色影院| 欧美日韩国产成人在线| 欧美成人精品激情在线观看| 国产69精品99久久久久久宅男| 国产成人精品日本亚洲专区61| 久久精品久久久久久国产 免费| 欧美性高潮在线| 国产精品嫩草视频| 国产精品久久一| 精品女同一区二区三区在线播放| 国产午夜精品一区二区三区| 91po在线观看91精品国产性色| 日本精品视频在线观看| 精品人伦一区二区三区蜜桃网站| 成人情趣片在线观看免费| 亚洲成av人片在线观看香蕉| 亚洲图片在线综合| 亚洲成人激情在线| 日本午夜精品理论片a级appf发布| 国产偷国产偷亚洲清高网站| 国产suv精品一区二区| 成人性生交xxxxx网站| 国产精品网站视频| 亚洲免费一在线| 色综合伊人色综合网| 精品无人国产偷自产在线| 欧美性20hd另类| 亚洲国产成人精品女人久久久|