JAVA 깊은 복사와 얕은 복사

Java Data Type

Primitive Data Type

  • 기본적(일반적)인 값을 기억하는 변수 타입
  • byte, short, int, float, double, char, boolean

Reference Data Type

  • 객체의 참조(Reference)값을 기억하는 변수
  • class, interface, 배열 등


얕은 복사 (shallow copy)

참조에 의한 복사

원본과 사본의 참조가 같이 이루어진다


깊은 복사 (deep copy)

새로운 객체를 만들어 값은 같지만 다른 참조를 가지는 복사


배열

얕은 복사

import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] a = {1, 2, 3, 4};
		
    int[] b = a;
		
    b[0] = 10;
		
    System.out.println(a);
    System.out.println(b);
		
    System.out.println(Arrays.toString(a));
    System.out.println(Arrays.toString(b));
  }
}
  • 출력
[I@7852e922
[I@7852e922
[10, 2, 3, 4]
[10, 2, 3, 4]
  • 두 배열의 주소값이 같고, 배열의 값이 함께 변경된 것을 확인할 수 있다


깊은 복사

import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    int[] a = {1, 2, 3, 4};
		
    int[] b = a.clone();
		
    b[0] = 10;
		
    System.out.println(a);
    System.out.println(b);
		
    System.out.println(Arrays.toString(a));
    System.out.println(Arrays.toString(b));
  }
}
  • 출력
[I@7852e922
[I@4e25154f
[1, 2, 3, 4]
[10, 2, 3, 4]
  • 두 배열의 주소값이 다르고 b 배열에서만 값의 변경이 일어났다.
  • 이 외에도
    • Object.clone()
    • Arrays.copyOf()
    • for문 을 통해 배열 원소에 접근하여 복사
  • 다차원 배열의 경우
    • 다중 for문을 이용하여 1차원 배열 형태로 접근가능할 때 위의 메서드들을 사용할 수 있다


ArrayList

얕은 복사

import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
		
    ArrayList<String> list2 = list;
    list2.add("d");
		
    System.out.println(list);
    System.out.println(list2);
  }
}
  • 출력
[a, b, c, d]
[a, b, c, d]
  • list2에 d를 추가했는데 list에도 추가된 것을 확인할 수 있다


깊은 복사

import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
		
    ArrayList<String> list2 = new ArrayList<>(list);
    list2.add("d");
		
    System.out.println(list);
    System.out.println(list2);
  }
}
  • 출력
[a, b, c]
[a, b, c, d]


class

얕은 복사

public class Main {
  public static void main(String[] args) {
    Student a = new Student("홍길동", 17, "010-1234-5678");
    Student b = a;
    b.name = "박보검";
		
    System.out.println(a);
    System.out.println(b);
  }
	
  static class Student {
    String name;
    int age;
    String phone;
		
    public Student(String name, int age, String phone) {
      this.name = name;
      this.age = age;
      this.phone = phone;
    }
    
    @Override
      public String toString() {
        return "Student [name=" + name + ", age=" + age + ", phone=" + phone + "]";
      }
  }
}
  • 출력
// toString 생성 전
Main$Student@7852e922
Main$Student@7852e922
// toString 생성 후
Student [name=박보검, age=17, phone=010-1234-5678]
Student [name=박보검, age=17, phone=010-1234-5678]
  • 두 객체가 가리키는 주소값이 같다


깊은 복사

public class Main {
  public static void main(String[] args) throws CloneNotSupportedException {
    Student a = new Student("홍길동", 17, "010-1234-5678");
    Student b = (Student) a.clone();
    b.name = "박보검";
		
    System.out.println(a);
    System.out.println(b);
  }
	
  static class Student implements Cloneable{
    String name;
    int age;
    String phone;
		
    public Student(String name, int age, String phone) {
      this.name = name;
      this.age = age;
      this.phone = phone;
    }

    @Override
    public String toString() {
      return "Student [name=" + name + ", age=" + age + ", phone=" + phone + "]";
    }
		
    @Override
    protected Object clone() throws CloneNotSupportedException {
      Student student = (Student) super.clone();
      student.name = this.name;
      student.age = this.age;
      student.phone = this.phone;
      return student;
    }
  }
}

  • 출력
// toString 생성 전
Main$Student@7852e922
Main$Student@4e25154f
// toString 생성 후
Student [name=홍길동, age=17, phone=010-1234-5678]
Student [name=박보검, age=17, phone=010-1234-5678]
  • 복사할 클래스에 Cloneable 인터페이스를 구현한 뒤 clone 메서드를 작성해주면 객체의 깊은 복사가 가능해진다.
  • 그 후 (객체타입) 복사할객체명.clone() 을 통해 복사 가능


태그:

카테고리:

업데이트: