浅拷贝:拷贝对象与原始对中的引用类型引用同一个对象(指针指向同一个对象)
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));
}
}