Java对象深复制与浅复制实例详解
Java对象深复制与浅复制实例详解
我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制
浅复制:对象的复制仅是对象本身,对象引用的其它对方并不会复制。
深复制:对象的复制包含对象引用的对象。
Java所有对象的基类提供了clone方法,但是这个方法是protectednative修饰,因此只暴露给之类去重写,外部是无法直接调用的。
我们现在来测试两种复制,首选是浅复制,浅复制要实现Cloneable接口。
//课程对象
classClass{
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
//学生对象
classUserimplementsCloneable{
privateStringname;
privateLongid;
//课程引用
privateClassc;
publicClassgetC(){
returnc;
}
publicvoidsetC(Classc){
this.c=c;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicLonggetId(){
returnid;
}
publicvoidsetId(Longid){
this.id=id;
}
@Override
protectedObjectclone()throwsCloneNotSupportedException{
returnsuper.clone();
}
@Override
publicinthashCode(){
returnsuper.hashCode();
}
@Override
publicbooleanequals(Objectobj){
if(objinstanceofUser){
Useruser=(User)obj;
if(this.id==user.getId()&&this.getName()==user.getName()){
returntrue;
}
if(user.getId().equals(this.id)
&&user.getName().equals(this.name)){
returntrue;
}
returnfalse;
}else
returnfalse;
}
}
我们来测试:
Useruser1=newUser();
Useruser2=user1;
Useruser3=(User)user1.clone();
System.out.println(user1==user2);
System.out.println(user3==user1);
System.out.println(user3.equals(user1));
System.out.println(user3.getName()==user3.getName());//true,浅复制
Classc=newClass();
c.setName("语文");
user1.setC(c);
//测试复制深度
Useruser4=(User)user1.clone();
System.out.println(user4.getC()==user1.getC());//true,说明引用的对象依然是同一个对象
对象的复制并没复制引用所指向的对象class,复制出来的引用指向的同一个地址。
深复制采用序列化与反序列的方式去获取,也有种说法类似于腌菜,用流的方式腌制进去又取出来,实现深度复制。
classCarimplementsSerializable{
/**
*
*/
privatestaticfinallongserialVersionUID=42342L;
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
//深复制
classPeopleimplementsSerializable{
/**
*
*/
privatestaticfinallongserialVersionUID=543535212412L;
privateCarcar;
publicCargetCar(){
returncar;
}
publicvoidsetCar(Carcar){
this.car=car;
}
publicPeopledeepClone()throwsIOException,ClassNotFoundException{
//腌制
ByteArrayOutputStreamout=newByteArrayOutputStream();
ObjectOutputStreamoos=newObjectOutputStream(out);
oos.writeObject(this);
//取出
ByteArrayInputStreaminput=newByteArrayInputStream(out.toByteArray());
ObjectInputStreamois=newObjectInputStream(input);
return(People)ois.readObject();
}
}
测试深复制:
//深复制
Carcar=newCar();
car.setName("benz");
Peoplep=newPeople();
p.setCar(car);
try{
Peoplep2=p.deepClone();
System.out.println(p2.getCar()==p.getCar());//false,说明引用的对象也进行了复制
}catch(ClassNotFoundException|IOExceptione){
e.printStackTrace();
}
例外提及一下生成对象的五种办法:
1.new
2.Class类的newInstance
3.Constructor类newInstance
4.Clone方式
5.反序列化的方式
其中2与3即是反射的方式。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
热门推荐
10 新人红包祝福语简短精辟
11 幼师给毕业祝福语简短
12 生日高考祝福语妹妹简短
13 下飞机祝福语简短英文
14 元宵发客户祝福语简短
15 爸妈金婚文案祝福语简短
16 新郎朋友红包祝福语简短
17 虎年五一祝福语大全简短
18 出阁宴祝福语姐姐简短