本文實例講述了java實現克隆的三種方式。分享給大家供大家參考,具體如下:
1、淺復制(淺克隆)這種淺復制,其實也就是把被復制的這個對象的一些變量值拿過來了。最后生成student2還是一個新的對象。
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
|
public class clonetest1 { public static void main(string[] args) throws exception { student1 student = new student1(); student.setage( 24 ); student.setname( "niesong" ); student1 student2 = (student1)student.clone(); //這個是調用下面的那個方法,然后把這個這個對象clone到student system.out.println( "age:" + student2.getage() + " " + "name:" + student2.getname()); system.out.println( "---------------------" ); student2.setage( 23 ); //克隆后得到的是一個新的對象,所以重新寫的是student2這個對象的值 system.out.println(student.getage()); system.out.println(student2.getage()); } } //克隆的對象必須實現cloneable這個接口,而且需要重寫clone方法 class student1 implements cloneable { private int age; //定義為private說明這個成員變量只能被被當前類中訪問,如果外部需要獲得,那么就只能通過getage方法進行獲取 private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } @override public object clone() throws clonenotsupportedexception { object object = super .clone(); return object; } } |
運行結果:
2、深復制(情況1使用的是在克隆的時候手動進行深克隆)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
public class clonetest2 { public static void main(string[] args) throws exception { teacher teacher = new teacher(); teacher.setage( 40 ); teacher.setname( "teacher zhang" ); student2 student2 = new student2(); student2.setage( 14 ); student2.setname( "lisi" ); student2.setteacher(teacher); student2 student3 = (student2)student2.clone(); //這里是深復制,所以這時候student2中的teacher就是teacher這個對象的一個復制,就和student3是student2的一個復制 //所以下面teacher.setname只是對他原來的這個對象更改,但是復制的那個并沒有更改 system.out.println(student3.getage()); system.out.println(student3.getname()); system.out.println(student3.getteacher().getage()); teacher.setname( "teacher niesong" ); //不會又任何影響 system.out.println(student3.getteacher().getname()); } } class student2 implements cloneable { private int age; private string name; private teacher teacher; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } public teacher getteacher() { return teacher; } public void setteacher(teacher teacher) { this .teacher = teacher; } @override public object clone() throws clonenotsupportedexception { //這一步返回的這個student2還只是一個淺克隆, student2 student2 = (student2) super .clone(); //然后克隆的過程中獲得這個克隆的student2,然后調用這個getteacher這個方方法得到這個teacher對象。然后實現克隆。在設置到這個student2中的teacher。 //這樣實現了雙層克隆使得那個teacher對象也得到了復制。 student2.setteacher((teacher)student2.getteacher().clone()); //雙層克隆使得那個teacher對象也得到了復制 return student2; } } class teacher implements cloneable { private int age; private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } @override public object clone() throws clonenotsupportedexception { return super .clone(); } } |
運行結果:
3、利用serializable實現深復制(這個是利用serializable,利用序列化的方式來實現深復制(深克隆),在其中利用了io流的方式將這個對象寫到io流里面,然后在從io流里面讀取,這樣就實現了一個復制,然后實現序列化的這個會將引用的那個對象也一并進行深復制,這樣就實現了這個機制,同時在io里面讀取數據的時候還使用了裝飾者模式)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.objectinputstream; import java.io.objectoutputstream; import java.io.serializable; public class clonetest3 { public static void main(string[] args) throws exception { teacher3 teacher3 = new teacher3(); teacher3.setage( 23 ); teacher3.setname( "niesong" ); student3 student3 = new student3(); student3.setage( 50 ); student3.setname( "wutao" ); student3.setteacher3(teacher3); student3 ss = (student3)student3.deepcopt(); system.out.println(ss.getage()); system.out.println(ss.getname()); system.out.println( "---------------------" ); system.out.println(ss.getteacher3().getage()); system.out.println(ss.getteacher3().getname()); system.out.println( "-----------------------" ); ss.getteacher3().setage( 7777 ); ss.getteacher3().setname( "hhhhh" ); system.out.println(teacher3.getage()); system.out.println(teacher3.getname()); //雖然上面的已經改了,但是改的是那個復制對象后的那個里面的,然后那個原來的那個里面的并沒有改,下面驗證::: system.out.println( "-----------------" ); system.out.println(ss.getteacher3().getage()); system.out.println(ss.getteacher3().getname()); } } class teacher3 implements serializable { // 上面的那個警告可以直接消除,除了使用在設置中不顯示這個警告,還可以使用下面的這兩條語句中的任何一條語句 // 這個serialversionuid為了讓該類別serializable向后兼容 // private static final long serialversionuid = 1l; // private static final long serialversionuid = 8940196742313994740l; private int age; private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } } class student3 implements serializable { private static final long serialversionuid = 1l; private int age; private string name; private teacher3 teacher3; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } public teacher3 getteacher3() { return teacher3; } public void setteacher3(teacher3 teacher3) { this .teacher3 = teacher3; } //使得序列化student3的時候也會將teacher序列化 public object deepcopt() throws exception { bytearrayoutputstream bos = new bytearrayoutputstream(); objectoutputstream oos = new objectoutputstream(bos); oos.writeobject( this ); //將當前這個對象寫到一個輸出流當中,,因為這個對象的類實現了serializable這個接口,所以在這個類中 //有一個引用,這個引用如果實現了序列化,那么這個也會寫到這個輸出流當中 bytearrayinputstream bis = new bytearrayinputstream(bos.tobytearray()); objectinputstream ois = new objectinputstream(bis); return ois.readobject(); //這個就是將流中的東西讀出類,讀到一個對象流當中,這樣就可以返回這兩個對象的東西,實現深克隆 } } |
運行結果:
希望本文所述對大家java程序設計有所幫助。
原文鏈接:https://blog.csdn.net/qq_28081081/article/details/80455150