所謂的對象克隆描述的概念就是進行對象的賦值,當一個對象創(chuàng)建完成之后實際上都會自動的開辟內(nèi)存空間,在每一塊堆內(nèi)存空間里面都會保存有對象的相關屬性內(nèi)容,所謂的對象克隆它描述的就是一個屬性的賦值。
如果要想完成對象的克隆操作,實際上不需要用戶特別復雜的處理,因為在Object類里面提供有一個專屬的對象克隆的處理方法,此方法定義如下:
protected native Object clone() throws CloneNotSupportedException;
通過clone()方法定義可以發(fā)現(xiàn),這個方法的操作實際上是直接利用了JVM底層完成的內(nèi)存空間復制處理,如果要想復制對象就必須使用指定的方法完成,同時該方法會拋出一個“CloneNotSupportedException”異常。
如果要克隆對象所處的類沒有實現(xiàn)Cloneable接口,那么就會出現(xiàn)以上的異常。Cloneable是在JDK1.0的時候就提供的支持,該接口中沒有提供任何的處理方法,所以此接口是一種標識性接口,表示一種能力。
范例:觀察對象克隆處理
class Emp implements Cloneable {
private String ename;
private String job;
public Emp(String ename, String job) {
this.ename = ename;
this.job = job;
}
@Override
public String toString() {
return super.toString() + "Emp{" +
"ename='" + ename + '\'' +
", job='" + job + '\'' +
'}';
}
@Override
public Object clone() throws CloneNotSupportedException { //讓此方法對外的類可見
return super.clone(); //調(diào)用父類方法
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Emp empA = new Emp("Jie", "程序員");
Emp empB = (Emp) empA.clone();
System.out.println(empA.toString());
System.out.println(empB.toString());
}
}
輸出:
Emp@2a139a55Emp{ename='Jie', job='程序員'}
Emp@15db9742Emp{ename='Jie', job='程序員'}
此時兩個對象的編碼內(nèi)容不同,所以得出的結(jié)論就是:利用empA對象的堆內(nèi)存空間拷貝得到了empB對象的 新的堆內(nèi)存空間,同時兩個空間的屬性內(nèi)容完全相同。
在實際的開發(fā)過程之中如果想要進行對象的克隆處理一般會有兩種做法:深克隆、淺克隆。所謂的深克隆指的是所有與對象有關的引用類型全部進行克隆。而所謂的淺克隆指的就是只克隆當前類的基本屬性內(nèi)容。
范例:淺克隆
class Dept { //部門類
private String dname;
private String loc;
public Dept(String dname, String loc) {
this.dname = dname;
this.loc = loc;
}
@Override
public String toString() {
return super.toString() + " - Dept{" +
"dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
}
class Emp implements Cloneable {
private String ename;
private String job;
private Dept dept; //與部門引用
public Emp(String ename, String job, Dept dept) {
this.ename = ename;
this.job = job;
this.dept = dept;
}
@Override
public String toString() {
return super.toString() + "Emp{" +
"ename='" + ename + '\'' +
", job='" + job + '\'' +
", dept=" + dept +
'}';
}
@Override
public Object clone() throws CloneNotSupportedException { //讓此方法對外的類可見
return super.clone(); //調(diào)用父類方法
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Dept dept = new Dept("研發(fā)部", "成都");
Emp empA = new Emp("Jie", "程序員", dept);
Emp empB = (Emp) empA.clone();
System.out.println(empA.toString());
System.out.println(empB.toString());
}
}
輸出:
Emp@2a139a55Emp{ename='Jie', job='程序員', dept=Dept@15db9742 - Dept{dname='研發(fā)部', loc='成都'}}
Emp@6d06d69cEmp{ename='Jie', job='程序員', dept=Dept@15db9742 - Dept{dname='研發(fā)部', loc='成都'}}
在Object類提供的clone()方法實際上屬于淺克隆的操作支持。
如果想要絲線深克隆就需要通過程序邏輯實現(xiàn)手工的拷貝處理,要想實現(xiàn)這樣的控制就必須熟悉反射機制。