拷贝,顾名思义就是复制,分配新的内存,产生新的对象,与new关键字类似。然而,拷贝中存在部分隐匿的差别,需要我们细细查看
// 学士:姓名 年龄 信息
public class Bachelor {
private String name;
private int age;
private Info info;
public Bachelor(String name,int age,Info info){
this.name = name;
this.age = age;
this.info = info;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
}
// 信息:技能 项目
class Info{
private String level;
private Project project;
public Info(String level,Project project){
this.level = level;
this.project = project;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
}
// 项目:项目名称
class Project{
private String projectName;
public Project(String projectName){
this.projectName = projectName;
}
}
- 引用拷贝
不同引用指向相同地址,并不分配新的内存空间;
// 测试代码
Project project = new Project("myApp");
Info info = new Info("A",project);
Bachelor bachelorOne = new Bachelor("Cheng",23,info);
Bachelor bachelorTwo = bachelorOne;
System.out.println(bachelorOne);
System.out.println(bachelorTwo);
// 打印出相同的地址
javaBasic.Bachelor@15db9742
javaBasic.Bachelor@15db9742
- 对象拷贝
// 实现Cloneable接口,复写clone()方法
public class Bachelor implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
Bachelor newBachelor = (Bachelor) super.clone();
return newBachelor;
}
}
// 测试代码
Project project = new Project("myApp");
Info info = new Info("A",project);
Bachelor bachelorOne = new Bachelor("Cheng",23,info);
Bachelor bachelorTwo = (Bachelor) bachelorOne.clone();
System.out.println(bachelorOne);
System.out.println(bachelorTwo);
System.out.println(bachelorOne.getName() == bachelorTwo.getName());
// 打印出不同地址,且name引用相同
javaBasic.Bachelor@15db9742
javaBasic.Bachelor@6d06d69c
true
- 浅拷贝
如上面测试代码,分配新的内存,创建新对象,但是name属性却存在相同的引用,即拷贝主对象,却不拷贝主对象里面的对象;
如何实现name属性的拷贝呢?
// 重新生成name对象
@Override
protected Object clone() throws CloneNotSupportedException {
Bachelor newBachelor = (Bachelor) super.clone();
newBachelor.name = new String(this.name);
return newBachelor;
}
按照此种逻辑,info对象也是浅拷贝,如何实现主对象中对象的拷贝呢?
// 类实现Cloneable接口,复写clone方法
// 在clone()方法中,实现主对象内对象的重新生成
public class Bachelor implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
Bachelor newBachelor = (Bachelor) super.clone();
newBachelor.name = new String(this.name);
newBachelor.info = (Info) this.info.clone();
return newBachelor;
}
}
class Info implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
Info newInfo = (Info) super.clone();
// 将level属性和project方法均重新生成
newInfo.level = new String(this.level);
newInfo.project = (Project) this.project.clone();
return newInfo;
}
class Project implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (Project) super.clone();
}
}
// 测试代码
Project project = new Project("myApp");
Info info = new Info("A",project);
Bachelor bachelorOne = new Bachelor("Cheng",23,info);
Bachelor bachelorTwo = (Bachelor) bachelorOne.clone();
System.out.println(bachelorOne);
System.out.println(bachelorTwo);
System.out.println(bachelorOne.getName() == bachelorTwo.getName());
System.out.println(bachelorTwo.getInfo() == bachelorOne.getInfo());
System.out.println(bachelorTwo.getInfo().getProject() == bachelorOne.getInfo().getProject());
// 实现主对象内部所有对象的拷贝
javaBasic.Bachelor@15db9742
javaBasic.Bachelor@6d06d69c
false
false
false
- 深拷贝
实现主对象全部结构的拷贝,包括主对象中的对象;