概念:
浅拷贝只复制源对象的地址,当源对象的属性值改变时,拷贝对象的值也随之改变。

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
实现深拷贝的方式:
- 构造方法
- 重新clone方法
- 序列化,实现Serializable 接口
重新clone方法代码:
public class Dept implements Cloneable{
private Integer id;
private String deptname;
public Dept(Integer id, String deptname) {
this.id = id;
this.deptname = deptname;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptname() {
return deptname;
}
public void setDeptname(String deptname) {
this.deptname = deptname;
}
@Override
public Dept clone() throws CloneNotSupportedException {
return (Dept) super.clone();
}
}
测试:
public class copyTest {
public static void main(String[] args) {
Dept dept01 = null;
Dept dept02 = null;
try {
dept01 = new Dept(1, "shanghai");
dept02 = dept01.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(dept01);
System.out.println(dept02);
}
}
结果: 两个对象的地址不一样

但如果说一个类中有引用类型的属性,那么必须重写该类的clone方法。
public class User implements Cloneable{
private String username;
private Integer password;
private Dept dept;
public User(String username, Integer password, Dept dept) {
this.username = username;
this.password = password;
this.dept = dept;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public void setPassword(Integer password) {
this.password = password;
}
@Override
public User clone() throws CloneNotSupportedException {
User user=(User) super.clone();
user.setDept(user.getDept().clone());
return user;
}
}
测试:
public class copyTest {
public static void main(String[] args) {
try {
Dept dept=new Dept(1,"beijing");
User user01=new User("zx",123,dept);
User user02=(User) user01.clone();
System.out.println(user01.getDept());
System.out.println(user02.getDept());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
结果:引用类型的属性地址是不一样的

如果我们不重写的话:
public class User implements Cloneable{
private String username;
private Integer password;
private Dept dept;
public User(String username, Integer password, Dept dept) {
this.username = username;
this.password = password;
this.dept = dept;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public void setPassword(Integer password) {
this.password = password;
}
@Override
public Object clone() throws CloneNotSupportedException {
// User user=(User) super.clone();
// user.setDept(user.getDept().clone());
// return user;
return super.clone();
}
}
测试
public class copyTest {
public static void main(String[] args) {
try {
Dept dept=new Dept(1,"beijing");
User user01=new User("zx",123,dept);
User user02=(User) user01.clone();
System.out.println(user01.getDept());
System.out.println(user02.getDept());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
结果:引用类型的属性地址是一样的


被折叠的 条评论
为什么被折叠?



