Java中对象的深复制和浅复制详解Word文档下载推荐.docx
《Java中对象的深复制和浅复制详解Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Java中对象的深复制和浅复制详解Word文档下载推荐.docx(10页珍藏版)》请在冰点文库上搜索。
implements
Cloneable
2.{
3.
String
name;
4.int
age;
5.
Student(String
name,int
age)
6.
{
7.
this.name=name;
8.
this.age=age;
9.
}
10.public
Object
clone()
11.
12.
o=null;
13.
try
14.
15.
o=(Student)super.clone();
//Object
中的clone()识别出你要复制的是哪一个对象。
16.
17.
catch(CloneNotSupportedException
e)
18.
19.
System.out.println(e.toString());
20.
21.
return
o;
22.
23.
24.public
static
void
main(String[]
args)
25.
26.
s1=new
Student("
zhangsan"
18);
27.
s2=(Student)s1.clone();
28.
s2.name="
lisi"
;
29.
s2.age=20;
30.
//修改学生2后,不影响学生1的值。
31.
System.out.println("
name="
+s1.name+"
"
+"
age="
+s1.age);
32.
+s2.name+"
+s2.age);
33.}
34.}
说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?
在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
②继承自java.lang.Object类的clone()方法是浅复制。
以下代码可以证明之。
1.class
Professor
4.
int
Professor(String
10.}
11.public
12.{
//
常量对象。
p;
学生1和学生2的引用值都是一样的。
age,Professor
p)
this.p=p;
22.public
24.
33.
o.p=(Professor)p.clone();
34.
35.
36.public
37.{
38.
p=new
Professor("
wangwu"
50);
39.
18,p);
40.
41.
s2.p.name="
42.
s2.p.age=30;
43.
+s1.p.name+"
+s1.p.age);
44.
+s2.p.name+"
+s2.p.age);
45.
//输出结果学生1和2的教授成为lisi,age为30。
46.
47.}
那应该如何实现深层次的克隆,即修改s2的教授不会影响s1的教授?
代码改进如下。
改进使学生1的Professor不改变(深层次的克隆)
o=super.clone();
23.}
25.{
35.public
36.
37.
//对引用的对象也进行复制
47.
48.
49.
50.public
51.
52.
53.
54.
55.
56.
57.
//学生1的教授不
改变。
58.
59.
60.}
61.}
3.利用串行化来做深复制(主要是为了避免重写比较复杂对象的深复制的clone()方法,也可以程序实现断点续传等等功能)
把对象写到流里的过程是串行化(Serilization)过程,但是在Java程序师圈子里又非常形象地称为“冷冻”或者“腌咸菜(picking)”过程;
而把对象从流中读出来的并行化(Deserialization)过程则叫做“解冻”或者“回鲜(depicking)”过程。
应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此“腌成咸菜”的只是对象的一个拷贝,Java咸菜还可以回鲜。
在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成咸菜),再从流里读出来(把咸菜回鲜),便可以重建对象。
如下为深复制源代码。
deepClone()
3.//将对象写到流里
4.ByteArrayOutoutStream
bo=new
ByteArrayOutputStream();
5.ObjectOutputStream
oo=new
ObjectOutputStream(bo);
6.oo.writeObject(this);
7.//从流里读出来
8.ByteArrayInputStream
bi=new
ByteArrayInputStream(bo.toByteArray());
9.ObjectInputStream
oi=new
ObjectInputStream(bi);
10.return(oi.readObject());
11.}
这样做的前提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可串行化的对象或属性可否设成transient,从而将之排除在复制过程之外。
上例代码改进如下。
Teacher
Serializable{
2.
public
Teacher(String
age){
8.}
9.public
10.String
//常量对象
11.int
12.Teacher
t;
//学生1和学生2的引用值都是一样的。
13.public
age,Teacher
t){
17.}
18.public
throws
IOException,
OptionalDataException,ClassNotFoundException{//将对象写到流里
ByteArrayOutoutStream
ObjectOutputStream
oo.writeObject(this);
//从流里读出来
ByteArrayInputStream
ObjectInputStream
return(oi.readObject());
26.}
27.public
args){
t=new
Teacher("
tangliang"
30);
18,t);
s2=(Student)s1.deepClone();
s2.t.name="
tony"
s2.t.age=40;
//学生1的老师不改变
+s1.t.name+"
+s1.t.age);
35.}
36.}
【责任编辑:
wangxueyanTEL:
(010)68476606】