깊은 복사, 얕은 복사에 관하여
얕은 복사, 깊은 복사
객체 지향 프로그래밍에서의 객체 복사는 기본 객체의 복사본을 만드는 것이다.
얕은 복사(shallow copy)
- 얕은 복사는
얕은 복사본
을 얻을 때마다 새 인스턴스를 만든다.- 개체의 모든 필드를 해당 새 인스턴스에 복사하고 개체 유형으로 반환하므로 명시적으로 원래 개체로 다시 캐스팅해야 한다.
- 객체 클래스의 clone() 메서드는 객체의
얕은 복사본
을 지원합니다.
public class Ex {
private int[] data;
public Ex(int[] values) {
data = values;
}
public void showData() {
System.out.println(Arrays.toString(data));
}
}
- 위의 코드를 그림으로
data
는 values
와 같은 배열(같은 주소값)을 참조하고 있다.
하지만 값의 요소가 다른 참조를 통해서 값이 변경된다면, 문제가 발생한다.
public class UsesEx{
public static void main(String[] args) {
int[] vals = {3, 7, 9};
Ex e = new Ex(vals);
e.showData(); // prints out [3, 7, 9]
vals[0] = 13;
e.showData(); // prints out [13, 7, 9]
}
}
- 위의 코드를 그림으로
깊은 복사(Deep copy)
- 깊은 복사는?
- 기본 구현을 사용하지 않기 위해 자체 복사본이 필요할 때마다 필요에 따라 구현해야 하는 개체의 깊은 복사본이 필요할 때마다 이를
깊은 복사본
이라고 합니다. - 따라서 전체 복사를 위해 모든 멤버 클래스가
Cloneable
인터페이스를 구현하고 객체 클래스의 clone() 메서드를 재정의하는지 확인해야 합니다.
- 기본 구현을 사용하지 않기 위해 자체 복사본이 필요할 때마다 필요에 따라 구현해야 하는 개체의 깊은 복사본이 필요할 때마다 이를
깊은 복사는 실제로 새 배열을 만들고 값을 복사하는 것을 의미합니다.
public class Ex {
private int[] data;
public Ex(int[] values) {
data = new int[values.length];
for (int i = 0; i < data.length; i++) {
data[i] = values[i];
}
}
public void showData() {
System.out.println(Arrays.toString(data));
}
}
- 위의 코드를 그림으로
얕은 복사와 달리 깊은 복사는 값의 요소를 변화시키지 않는다.
배열 값을 변경해도 배열 데이터는 변경되지 않습니다.
public class UsesEx{
public static void main(String[] args) {
int[] vals = {3, 7, 9};
Ex e = new Ex(vals);
e.showData(); // prints out [3, 7, 9]
vals[0] = 13;
e.showData(); // prints out [3, 7, 9]
}
}