Java中clone方法以及深複製和淺複製
阿新 • • 發佈:2019-01-24
Java中處理基本資料型別(如:int , char , double等),都是採用按值傳遞的方式執行,除此之外的其他型別都是按照引用傳遞(傳遞的是一個物件的引用)的方式執行。物件在函式呼叫時和使用“=”賦值時都是引用傳遞。
Java中clone方法的作用是為了在現實程式設計中解決這樣一個問題:
從某個已有的物件A創建出另外一個與A具有相同狀態的物件B,並且對B的修改不會影響到物件A。
Java中所有的類都繼承自Object類,該類中有一個clone方法,那麼我們如何使用clone()方法呢?具體步驟如下:
1.實現clone的類,首先要繼承Cloneable介面。Cloneable介面實質上是一個標誌介面,沒有任何介面方法;
2.在類中重寫clone()方法;
3.在clone方法中呼叫super.clone();
4.把淺複製的引用指向原型物件新的克隆體;
對上面的例子,引入clone()方法如下:
package com.JinLing.demo1;
//淺複製例子
class Obj implements Cloneable{
private int aInt = 0;
public int getaInt() {
return aInt;
}
public void setaInt(int aInt) {
this.aInt = aInt;
}
public void changeInt(){
this.aInt = 1;
}
public Object clone(){
Object o = null;
try {
o = (Obj)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
public class Demo3 {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = (Obj) a.clone();
b.changeInt();
System.out.println("a:"+a.getaInt());
System.out.println("b:"+b.getaInt());
}
}
程式執行的結果:
a:0
b:1
但是當類中包含了一些物件時,就需要用到深複製,實現方法是對物件呼叫clone()方法完成複製之後,接著對物件中的非基本資料型別也呼叫clone()方法完成深複製。eg:
//深複製的例子
class Obj implements Cloneable{
Date birth = new Date();
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public void changeDate(){
this.birth.setMonth(4);
}
public Object clone(){
Object o = null;
try {
o = (Obj)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//實現深複製
birth = (Date)this.getBirth().clone();
return o;
}
}
public class Demo3 {
public static void main(String[] args) {
Obj a = new Obj();
Obj b = (Obj) a.clone();
b.changeDate();
System.out.println("a:"+a.getBirth());
System.out.println("b:"+b.getBirth());
}
}
執行結果為:
a:Sun Nov 13 10:05:14 CST 2016
b:Fri May 13 10:05:14 CST 2016
問:深複製和淺複製的區別?
答:淺複製是被複制物件的所有變數都含有與原來物件相同的值,而所有對其他物件的引用仍然指向原來的物件。
深複製是被複制物件的所有變數都含有與原來物件相同的值,那些引用變數將指向被複制的新物件,而不再是原有的那些被引用的物件。深複製是把複製的物件所引用的物件都複製了一邊。