얕은 복사와 깊은 복사는 객체 지향 프로그래밍에서 주로 사용되는 용어다.
복사를 할 때, 데이터의 크기나 복잡도에 따라서 얕은 복사와 깊은 복사를 선택해야 한다.
얕은 복사는 객체의 주소 값을 복사하기 때문에, 복사 된 객체와 원본 객체가 같은 객체를 참조한다.
이는 원본 객체와 복사된 객체가 동일한 메모리 위치를 가리키고 있는 상태이다.
따라서 원본 객체나 복사된 객체 중 하나에서 데이터가 변경되면,
다른 객체도 변경된 데이터를 참조하게 된다.(함께 변경된다.)
class Point {
public int x;
public int y;
}
public class Main {
public static void main(String[] args) {
Point original = new Point();
original.x = 5;
original.y = 10;
Point copy = original; // 얕은 복사
copy.x = 15;
System.out.println(original.x); // 출력 결과: 15
}
}
위의 예제에서 original 객체와 copy 객체는 동일한 메모리 위치를 가리키고 있으므로,
copy.x = 15; 로 copy 객체의 x 값을 변경하면 original 객체의 x 값도 함께 변경된다.
깊은 복사는 객체의 내부 구조를 모두 새로운 객체에 복사하기 때문에, 복사된 객체와 원본 객체는 서로 다른 객체를 참조한다.
이는 객체의 내용을 새로운 메모리 공간에 복사하는 것을 의미한다.
즉, 복사된 객체는 원본 객체와는 별개의 메모리 위치를 가지게 된다.
원본 객체와 복사된 객체는 서로 독립적으로 동작하며, 한 객체에서 데이터를 변경해도 다른 객체에 영향을 주지 않는다.
자바에서 객체의 깊은 복사를 위해서는 clone() 메서드를 사용하거나, 직접 필드의 값을 복사하는 방법을 사용할 수 있다. 다음은 clone() 메서드를 사용하여 객체를 깊은 복사하는 예제이다.
class Point implements Cloneable {
public int x;
public int y;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) {
Point original = new Point();
original.x = 5;
original.y = 10;
Point copy;
try {
copy = (Point) original.clone(); // 깊은 복사
copy.x = 15;
System.out.println(original.x); // 출력 결과: 5
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
clone() 메서드를 호출하고 original 객체를 깊은 복사하여 copy 객체를 생성했다.
copy.x = 15; 로 copy 객체의 x 값을 변경해도 original 객체의 x 값은 변경되지 않는다.
+) 깊은 복사는 복사할 객체의 크기나 복잡성에 따라 성능상의 부담을 줄 수 있다는 것을 고려해야 한다.