当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选面试题-什么是浅拷贝和深拷贝?

金三银四精选面试题-什么是浅拷贝和深拷贝?

来源:图灵教育
时间:2023-11-15 09:18:33
 

什么是浅拷贝和深拷贝?

浅拷贝(shallow copy):只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存;

深拷贝(deep copy):复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变;

浅拷贝

拷贝对象和原始对象的引用类型引用同一个对象。

public class ShallowCloneExample implements Cloneable {

  private int[] arr;

  public ShallowCloneExample() {
    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 ShallowCloneExample clone() throws CloneNotSupportedException {
    return (ShallowCloneExample) super.clone();
  }

}

ShallowCloneExample e1 = new ShallowCloneExample();
ShallowCloneExample e2 = null;
try {
  e2 = e1.clone();
} catch (CloneNotSupportedException e) {
  e.printStackTrace();
}

e1.set(2, 222);
System.out.println(e2.get(2)); // 222

深拷贝

拷贝对象和原始对象的引用类型引用不同对象。

public class DeepCloneExample implements Cloneable {

  private int[] arr;

  public DeepCloneExample() {
    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 DeepCloneExample clone() throws CloneNotSupportedException {
    DeepCloneExample result = (DeepCloneExample) super.clone();
    result.arr = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
      result.arr[i] = arr[i];
    }

    return result;
  }

}

DeepCloneExample e1 = new DeepCloneExample();
DeepCloneExample e2 = null;
try {
  e2 = e1.clone();
} catch (CloneNotSupportedException e) {
  e.printStackTrace();
}

e1.set(2, 222);
System.out.println(e2.get(2)); // 2

使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。

public class CloneConstructorExample {

  private int[] arr;

  public CloneConstructorExample() {
    arr = new int[10];
    for (int i = 0; i < arr.length; i++) {
      arr[i] = i;
    }
  }

  public CloneConstructorExample(CloneConstructorExample original) {
    arr = new int[original.arr.length];
    for (int i = 0; i < original.arr.length; i++) {
      arr[i] = original.arr[i];
    }
  }

  public void set(int index, int value) {
    arr[index] = value;
  }

  public int get(int index) {
    return arr[index];
  }

}

CloneConstructorExample e1 = new CloneConstructorExample();
CloneConstructorExample e2 = new CloneConstructorExample(e1);
e1.set(2, 222);
System.out.println(e2.get(2)); // 2