java的clone机制

[b]首先了解下,什么叫作clone,以及深拷贝和浅拷贝的区别?[/b]
对象clone机制,是指根据源对象clone一个对象,这个clone对象与原来的对象相互隔离,但是内容相同。
即:
source != source.clone();
source.getClass()=source.clone().getClass();
source.equalWith(source.clone());
[b]浅拷贝[/b]:浅拷贝是指对象的引用类型成员变量拷贝的只是变量所存的内存地址,而不是引用类型成员变量所指内存的内容。即拷贝对象与原对象引用类型成员变量指向同一个内存。
a为原对象,b是拷贝对象
[img]http://ttkktt.iteye.com/upload/attachment/105013/7d8795ec-02ff-3863-a9d3-b655146304f8.jpg[/img]
[b]深拷贝[/b]:是不仅基本数据类型被拷贝,引用类型的成员变量拷贝的是变量所指内存。使得拷贝对象和原对象的引用类型成员变量也相互隔离开,做到了拷贝对象与原对象完全的隔离。
a为原对象,b是拷贝对象
[img]http://ttkktt.iteye.com/upload/attachment/105015/1d7a5fe2-eb79-3563-a55c-e01354bc5a19.jpg[/img]

[b]然后我们来讲讲,了解下java自带的clone机制——浅拷贝[/b]
java的object对象有一个clone方法,它的具体实现是由native方法实现的,效率较高。它是一个浅拷贝。

package clonetest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public final class Acount implements Cloneable{
private int i;
private String words = "haha";
private User user;
public Acount(int i,User user){
this.i = i;
this.user = user;
}
/*@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Acount copy = (Acount) super.clone();
if(user!=null){
copy.user = (User) user.clone();
}
return copy;
}*/
public static Object copy(Object o) throws IOException, ClassNotFoundException{
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bs);
os.writeObject(o);
os.flush();
ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
ObjectInputStream ois = new ObjectInputStream(is);
return ois.readObject();

}
public static void main(String args[]){
try {
User user = new User("zbq",22);
Acount source = new Acount(0,user);
Acount clone = (Acount)(source.clone());
System.out.println("source==clone:"+(source==clone));
System.out.println("source.i==clone.i:"+(source.i==clone.i));
source.i=1;
System.out.println("after change,source.i==clone.i:"+(source.i==clone.i));
System.out.println("source.words==clone.words:"+(source.words==clone.words));
source.words="byebye";
System.out.println("after change,source.words==clone.words:"+(source.words==clone.words));
System.out.println("source.user==clone.user:"+(source.user==clone.user));
source.user.name = "lxl";
System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
System.out.println(clone.user.name);
source.user = new User("",1);
System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class User implements Cloneable{
private String name;
private int age;
public User(String name,int age){
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}

}

}

[b]实现clone的步骤[/b]
1 声明实现Cloneable接口。
2 调用super.clone拿到一个对象,如果父类的clone实现没有问题的话,在该对象的内存存储中,所有父类定义的field都已经clone好了,该类中的primitive和不可变类型引用也克隆好了,可变类型引用都是浅copy。
3 把浅copy的引用指向原型对象新的克隆体。

[b]自己来实现深拷贝[/b]
package clonetest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public final class Acount implements Cloneable{
private int i;
private String words = "haha";
private User user;
public Acount(int i,User user){
this.i = i;
this.user = user;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Acount copy = (Acount) super.clone();
if(user!=null){
copy.user = (User) user.clone();
}
return copy;
}
public static Object copy(Object o) throws IOException, ClassNotFoundException{
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bs);
os.writeObject(o);
os.flush();
ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
ObjectInputStream ois = new ObjectInputStream(is);
return ois.readObject();

}
public static void main(String args[]){
try {
User user = new User("zbq",22);
Acount source = new Acount(0,user);
Acount clone = (Acount)(source.clone());
System.out.println("source==clone:"+(source==clone));
System.out.println("source.i==clone.i:"+(source.i==clone.i));
source.i=1;
System.out.println("after change,source.i==clone.i:"+(source.i==clone.i));
System.out.println("source.words==clone.words:"+(source.words==clone.words));
source.words="byebye";
System.out.println("after change,source.words==clone.words:"+(source.words==clone.words));
System.out.println("source.user==clone.user:"+(source.user==clone.user));
source.user.name = "lxl";
System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
System.out.println(clone.user.name);
source.user = new User("",1);
System.out.println("after change,source.user==clone.user:"+(source.user==clone.user));
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class User implements Cloneable{
private String name;
private int age;
public User(String name,int age){
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}

}

}

[b][i]使用Serializable方式来实现深拷贝[/i][/b]
前提是相关类必须都实现Serializable接口,且可能因为版本更换,老版本的序列化对象无法反序列化。
	
public static Object copy(Object o) throws IOException, ClassNotFoundException{
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bs);
os.writeObject(o);
os.flush();
os.close();
ByteArrayInputStream is = new ByteArrayInputStream(bs.toByteArray());
ObjectInputStream ois = new ObjectInputStream(is);
Object o1 = ois.readObject();
ois.close();
is.close();
bs.close();
return o1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值