자바 의 깊 은 복사 (깊 은 복사) 와 얕 은 복사 (얕 은 복사) 소개

6267 단어
깊 은 복사 (깊 은 복사) 와 얕 은 복사 (얕 은 복사) 는 비교적 통용 되 는 개념 이다. 특히 C + + 언어 에서 이해 하지 못 하면 delete 에 문제 가 생 길 수 있 지만 우 리 는 여기 서 자바 를 사용 해서 다행이다.자바 자동 관리 대상 의 회수 에 도 불구 하고 심 복사 (심 복사) 와 얕 은 복사 (얕 은 복사) 에 대해 우 리 는 충분 한 중 시 를 해 야 한다. 왜냐하면 가끔 은 이 두 개념 이 우리 에 게 적지 않 은 곤 혹 스 러 움 을 줄 수 있 기 때문이다.
얕 은 복사 란 대상 을 복사 할 때 대상 자체 (대상 의 기본 변수 포함) 만 복사 하고 대상 에 포 함 된 참조 대상 을 복사 하지 않 는 것 을 말한다.딥 카피 대상 자 체 는 물론 카피 대상 에 포 함 된 인용 이 가리 키 는 모든 대상 이다.예 를 들 어 더욱 명확 하 다. 대상 A1 에는 B1 에 대한 인용 이 포함 되 어 있 고 B1 에는 C1 에 대한 인용 이 포함 되 어 있다.얕 은 복사 A1 은 A2 를 얻 었 고 A2 에는 B1 에 대한 인용 이 포함 되 어 있 으 며 B1 에는 C1 에 대한 인용 이 포함 되 어 있다.깊 은 복사 본 은 얕 은 복사 본 에 대한 재 귀 이 고 깊 은 복사 A1 은 A2 를 얻 으 며 A2 에는 B2 (B1 의 copy) 에 대한 인용 이 포함 되 어 있 으 며 B2 에는 C2 (C1 의 copy) 에 대한 인용 이 포함 되 어 있다.
clone () 방법 을 고치 지 않 으 면 이 방법 으로 얻 은 대상 은 얕 은 복사 입 니 다. 다음은 깊 은 복사 에 중심 을 두 고 이야기 하 겠 습 니 다.
아래 프로그램 을 실행 하고 얕 은 복사 본 을 보십시오.

class Professor0 implements Cloneable { 
  String name; 
  int age; 
 
  Professor0(String name, int age) { 
    this.name = name; 
    this.age = age; 
  } 
 
  public Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
  } 
} 
 
class Student0 implements Cloneable { 
  String name;//     。 
  int age; 
  Professor0 p;//   1   2         。 
 
  Student0(String name, int age, Professor0 p) { 
    this.name = name; 
    this.age = age; 
    this.p = p; 
  } 
 
  public Object clone() { 
    Student0 o = null; 
    try { 
      o = (Student0) super.clone(); 
    } catch (CloneNotSupportedException e) { 
      System.out.println(e.toString()); 
    } 
 
    return o; 
  } 
} 
 
public class ShallowCopy { 
  public static void main(String[] args) { 
    Professor0 p = new Professor0("wangwu", 50); 
    Student0 s1 = new Student0("zhangsan", 18, p); 
    Student0 s2 = (Student0) s1.clone(); 
    s2.p.name = "lisi"; 
    s2.p.age = 30; 
    s2.name = "z"; 
    s2.age = 45; 
    System.out.println("  s1   :" + s1.name + "
s1 :" + s1.p.name + "," + "
s1 " + s1.p.age);// 1 } }

s2 는 변 했 지만 s1 도 변 했다. s1 의 p 와 s2 의 p 가 같은 대상 을 가리 키 는 것 을 증명 한다.이것 은 우리 가 가지 고 있 는 실제 수요 에서 그렇지 않 기 때문에 우 리 는 깊이 복사 해 야 한다.

class Professor implements Cloneable { 
  String name; 
  int age; 
 
  Professor(String name, int age) { 
    this.name = name; 
    this.age = age; 
  } 
 
  public Object clone() { 
    Object o = null; 
    try { 
      o = super.clone(); 
    } catch (CloneNotSupportedException e) { 
      System.out.println(e.toString()); 
    } 
    return o; 
  } 
} 
 
class Student implements Cloneable { 
  String name; 
  int age; 
  Professor p; 
 
  Student(String name, int age, Professor p) { 
    this.name = name; 
    this.age = age; 
    this.p = p; 
  } 
 
  public Object clone() { 
    Student o = null; 
    try { 
      o = (Student) super.clone(); 
    } catch (CloneNotSupportedException e) { 
      System.out.println(e.toString()); 
    } 
    o.p = (Professor) p.clone(); 
    return o; 
  } 
} 
 
public class DeepCopy { 
  public static void main(String args[]) { 
    long t1 = System.currentTimeMillis(); 
    Professor p = new Professor("wangwu", 50); 
    Student s1 = new Student("zhangsan", 18, p); 
    Student s2 = (Student) s1.clone(); 
    s2.p.name = "lisi"; 
    s2.p.age = 30; 
    System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);//   1      。 
    long t2 = System.currentTimeMillis(); 
    System.out.println(t2-t1); 
  } 
}

물론 우 리 는 대상 을 직렬 화 하 는 깊 은 복사 방법 도 있다.

import java.io.*; 
//Serialization is time-consuming 
class Professor2 implements Serializable { 
  /** 
   * 
   */
  private static final long serialVersionUID = 1L; 
  String name; 
  int age; 
 
  Professor2(String name, int age) { 
    this.name = name; 
    this.age = age; 
  } 
} 
 
class Student2 implements Serializable { 
  /** 
   * 
   */
  private static final long serialVersionUID = 1L; 
  String name;//     。 
  int age; 
  Professor2 p;//   1   2         。 
 
  Student2(String name, int age, Professor2 p) { 
    this.name = name; 
    this.age = age; 
    this.p = p; 
  } 
 
  public Object deepClone() throws IOException, OptionalDataException, 
      ClassNotFoundException { 
    //         
    ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
    ObjectOutputStream oo = new ObjectOutputStream(bo); 
    oo.writeObject(this); 
    //        
    ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); 
    ObjectInputStream oi = new ObjectInputStream(bi); 
    return (oi.readObject()); 
  } 
 
} 
 
public class DeepCopy2 { 
 
  /** 
   * @param args 
   */
  public static void main(String[] args) throws OptionalDataException, 
      IOException, ClassNotFoundException { 
    long t1 = System.currentTimeMillis(); 
    Professor2 p = new Professor2("wangwu", 50); 
    Student2 s1 = new Student2("zhangsan", 18, p); 
    Student2 s2 = (Student2) s1.deepClone(); 
    s2.p.name = "lisi"; 
    s2.p.age = 30; 
    System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); //   1      。 
    long t2 = System.currentTimeMillis(); 
    System.out.println(t2-t1); 
  } 
 
}

그러나 직렬 화 는 시간 이 많이 걸린다. 일부 구조 에서 우 리 는 그들 이 대상 을 직렬 화 한 후에 전달 하 는 데 시간 이 많이 걸 린 다 는 것 을 느 낄 수 있다.

좋은 웹페이지 즐겨찾기