淺拷貝:拷貝對象與原始對中的引用類型引用同一個對象(指針指向同一個對象)
public class CloneDemo implements Cloneable{
private int[] arr;
public CloneDemo(){
arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
}
public void set(int index, int value) {
arr[index] = value;
}
public int get(int index) {
return arr[index];
}
/**
* 淺拷貝:拷貝對象與原始對中的引用類型引用同一個對象(指針指向同一個對象)
*
@Override
protected DeepCloneDemo clone() throws CloneNotSupportedException {
return (DeepCloneDemo) super.clone();
}
*/
深拷貝: 拷貝對象和原始對象中的引用類型引用(指針指向)不同對象
/**
* 深拷貝: 拷貝對象和原始對象中的引用類型引用(指針指向)不同對象
* @return
* @throws CloneNotSupportedException
*/
@Override
protected CloneDemo clone() throws CloneNotSupportedException {
CloneDemo res = (CloneDemo) super.clone();
res.arr = new int[arr.length]; //指針指向了新的內存空間
for (int i = 0; i < arr.length; i++) {
res.arr[i] = arr[i];
}
return res;
}
public static void main(String[] args) {
CloneDemo e1 = new CloneDemo();
CloneDemo e2 = null;
try {
e2 = e1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
e1.set(2, 222);
System.out.println(e2.get(2)); // 222
e2.set(2,111);
System.out.println(e1.get(2)); // 111
System.out.println(e1);
System.out.println(e2);
}
}
這種方式的缺點:拷貝一個對象即複雜又有風險,它會拋出異常,並且還需要類型轉換。
使用拷貝構造函數或者拷貝工廠來拷貝對象
public class CloneConstructorDemo {
/**
* 最好使用拷貝構造函數或者拷貝工廠來拷貝對象,安全。
*/
private int[] arr;
public CloneConstructorDemo(){
arr = new int[10]; //this.arr
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
}
public CloneConstructorDemo(CloneConstructorDemo original){
arr = new int[original.arr.length]; //e2.arr = new int[e1.arr.length];
for (int i = 0; i < original.arr.length; i++) {
arr[i] = original.arr[i];
}
}
public void setValue(int index, int value) {
arr[index] = value;
}
public int getValue(int index) {
return arr[index];
}
public static void main(String[] args) {
CloneConstructorDemo e1 = new CloneConstructorDemo();
CloneConstructorDemo e2 = new CloneConstructorDemo(e1);
e1.setValue(2,11);
System.out.println(e2.getValue(2));
}
}