国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 實例分析java對象中淺克隆和深克隆

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

2021-06-03 11:40Java之家 Java教程

在本篇文章中我們給大家分享了關于java對象中淺克隆和深克隆的相關知識點和相關代碼內容,有興趣的朋友們學習下。

引言:

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

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

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

?
1
protected native object clone() throws clonenotsupportedexception;

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

?
1
2
3
4
@override
protected object clone() throws clonenotsupportedexception {   
 return super.clone();
}

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

淺克隆:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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也修改了。而要想不被影響,就需要深克隆了。

深克隆:

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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接口,也是標記接口,最后同序列化和反序列化操作達到克隆的目的(包括數組的復制)。序列化和反序列化的知識請參照下一篇

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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}}

帶數組屬性的克隆

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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);
  }
}

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产毛片av| 另类亚洲专区 | 国产欧美精品区一区二区三区 | 亚洲欧洲av在线 | 免费在线成人网 | 亚洲综合色网 | 国产视频亚洲 | 亚洲一区二区三区四区五区中文 | 性视频一区二区 | 亚洲精品夜夜夜 | 日韩福利视频 | 国产91久久久久蜜臀青青天草二 | 黄色三级视频 | 涩涩999| 午夜午夜精品一区二区三区文 | 精品一区二区在线观看 | 亚洲综合自拍 | 内地农村三片在线观看 | 亚洲狠狠丁香婷婷综合久久久 | 国产中文一区二区三区 | 黄色av影视 | 久久久久黄 | 午夜精品久久久久久久 | 国产精品成人av | 日韩一区二区三区在线观看 | 精品久久精品 | 成人综合av | 成人a在线视频免费观看 | 欧美日韩免费在线 | 欧美在线观看免费观看视频 | 久久久日本 | 免费在线看a | 热久久国产 | 亚洲综合av在线播放 | 久久久www | 国产在线观看一区二区 | 97久久精品人人做人人爽50路 | 亚洲国产精品一区二区久久 | 99精品视频免费 | sis001亚洲原创区 | 欧美久久精品 |