拷貝,顧名思義就是復(fù)制,分配新的內(nèi)存,產(chǎn)生新的對(duì)象,與new關(guān)鍵字類似。然而,拷貝中存在部分隱匿的差別,需要我們細(xì)細(xì)查看
// 學(xué)士:姓名 年齡 信息
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;
}
}
// 信息:技能 項(xiàng)目
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;
}
}
// 項(xiàng)目:項(xiàng)目名稱
class Project{
private String projectName;
public Project(String projectName){
this.projectName = projectName;
}
}
- 引用拷貝
不同引用指向相同地址,并不分配新的內(nèi)存空間;
// 測(cè)試代碼
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
- 對(duì)象拷貝
// 實(shí)現(xiàn)Cloneable接口,復(fù)寫clone()方法
public class Bachelor implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
Bachelor newBachelor = (Bachelor) super.clone();
return newBachelor;
}
}
// 測(cè)試代碼
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
- 淺拷貝
如上面測(cè)試代碼,分配新的內(nèi)存,創(chuàng)建新對(duì)象,但是name屬性卻存在相同的引用,即拷貝主對(duì)象,卻不拷貝主對(duì)象里面的對(duì)象;
如何實(shí)現(xiàn)name屬性的拷貝呢?
// 重新生成name對(duì)象
@Override
protected Object clone() throws CloneNotSupportedException {
Bachelor newBachelor = (Bachelor) super.clone();
newBachelor.name = new String(this.name);
return newBachelor;
}
按照此種邏輯,info對(duì)象也是淺拷貝,如何實(shí)現(xiàn)主對(duì)象中對(duì)象的拷貝呢?
// 類實(shí)現(xiàn)Cloneable接口,復(fù)寫clone方法
// 在clone()方法中,實(shí)現(xiàn)主對(duì)象內(nèi)對(duì)象的重新生成
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();
}
}
// 測(cè)試代碼
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());
// 實(shí)現(xiàn)主對(duì)象內(nèi)部所有對(duì)象的拷貝
javaBasic.Bachelor@15db9742
javaBasic.Bachelor@6d06d69c
false
false
false
- 深拷貝
實(shí)現(xiàn)主對(duì)象全部結(jié)構(gòu)的拷貝,包括主對(duì)象中的對(duì)象;