对象的浅拷贝
来源:互联网 发布:淘宝手机充值退款 编辑:程序博客网 时间:2024/05/07 14:42
一个类实现Cloneable接口,那么它就具有了被拷贝的能力,如覆写clone方法之后就完全具备拷贝的能力。因为拷贝是在内存中进行的,所以在性能上比new生成对象要快很多,那么,拷贝是完全拷贝吗?下面看一个例子。
public class Person implements Cloneable{
//姓名
private String name;
//父亲
private Person father;
public Person(String name) {
super();
this.name = name;
}
public Person(String name, Person father) {
super();
this.name = name;
this.father = father;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getFather() {
return father;
}
public void setFather(Person father) {
this.father = father;
}
//实现拷贝
@Override
public Person clone(){
Person p=null;
try {
p=(Person)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
在这边我们定义了一个Person类,现在要描述一个场景,一个父亲有两个儿子,小儿子通过拷贝大儿子对象来生成,下面看下测试的方法。
这边可以看到输出的没有问题,那么突然有一天,父亲想让大儿子去认一个义父,也就是图上注释掉的代码,将代码写到小儿子命名完后。那么结果会如何呢?
可以看到小儿子的父亲也变了!这是为什么呢?因为拷贝时super.clone()方法调用的是Object的方法,就是这个方法的原因,它是一种浅拷贝的方式。也就是说不是把对象的所有属性拷贝一份,而是有选择性的拷贝。拷贝的规则如下:
基本类型
如果变量是基本类型,则拷贝值。
对象
如果对象是一个实例遍历,则拷贝地址引用,也就是说拷贝出来新的对象与原有的对象共享该实例变量。
String字符串
这个比较特殊,拷贝的是一个地址,是个引用,但是在修改的时候,他会在字符串池中重新生成新的字符串,原有的字符串对象保持不变。
所以也就是说,小儿子的对象是通过拷贝大儿子产生的,父亲是同一个,也就是同一个对象。于是修改了大儿子的父亲值,小儿子也跟着修改了。同理改小儿子的父亲也是一样,大儿子也会跟着修改。
那么怎么改呢?就是在拷贝的时候生成新的对象就可以了。
public Person clone(){
Person p=null;
try {
p=(Person)super.clone();
p.setFather(new Person(p.getFather().getName()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
- 对象的浅拷贝
- java对象的深拷贝浅拷贝
- C#对象的浅拷贝,深拷贝
- 对象的深拷贝,浅拷贝
- C#对象的浅拷贝,深拷贝
- 对象的深拷贝与浅拷贝
- 对象的深拷贝和浅拷贝
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Python对象的拷贝,浅拷贝和深拷贝。
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
- c#的对象的深拷贝和浅拷贝
- C++类对象的深拷贝、浅拷贝构造函数
- python对象的浅拷贝和深拷贝
- C++类对象的深拷贝、浅拷贝构造函数
- C++类对象的深拷贝、浅拷贝构造函数
- 关于异常EXCEPTION
- Java call by value 和 by reference (值传递和引用传递)
- ORA-01113,ORA-01110的简单解决
- java和matlab混合编程
- 射线
- 对象的浅拷贝
- 后台代码:大客户资料
- linux 命令\操作 备忘录
- CByteArray源码解析
- AngularJS实践与应用
- bootstrap-datepicker日期范围
- 势函数
- ViewStub使用学习
- 电信宽带错误代码