# Table of Contents
# 복사
객체 지향 프로그래밍에서는 얕은 복사와 깊은 복사를 구분해야한다.
# 원시 타입의 값 복사
예제를 살펴보자. 다음과 같이 int타입의 변수 a를 생성하고 값을 할당하자.
int a = 10;
메모리 구조는 다음과 같다.

변수 b를 설정하고 값을 할당하자.
int a = 10;
int b = a;

이제 변수 a의 값을 변경하자. a를 변경해도 b는 영향받지 않는다.
int a = 10;
int b = a;
a = 20;

이처럼 원시타입의 값 복사는 대입연산자(=)를 사용해도 문제가 없다.
# 참조 타입의 얕은 복사
얕은 복사의 예제를 살펴보자. Person타입의 변수 p1을 생성하고 객체를 할당하자.
Person p1 = new Person("Paul");
메모리 구조는 다음과 같다.

참조 타입의 얕은 복사(shallow copy)는 대입 연산자(=)를 사용한다
Person p1 = new Person("Paul");
Person p2 = p1;
메모리 구조는 다음과 같다.

# 얕은 복사의 문제점
이제 변수 p1이 가리키는 객체의 속성을 변경해보자.
Person p1 = new Person("Paul");
Person p2 = p1;
p1.setName("Monica")
System.out.println(p1.getName());
System.out.println(p2.getName());
출력값을 확인해보자
Monica
Monica
변수 p1가 가리키는 객체의 속성값을 변경했는데 변수 p2가 가리키는 객체의 속성값도 변경됐다. 대입 연산자(=)를 통한 얕은 복사는 두 변수가 같은 객체를 가리키기 때문이다.
# 깊은 복사
완전히 같은 속성 값을 가진 새로운 객체를 복사하면서, 이전 객체에는 아무런 영향이 없도록 하는 것을 깊은 복사(Deep copy)라고 한다.
깊은 복사를 사용하려면 Cloneable인터페이스를 구현하고 clone()메소드를 오버라이드해야한다.
class Person implements Cloneable {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
이제 다음과 같이 깊은 복사를 할 수 있다.
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Paul");
try {
Person p2 = (Person) p1.clone();
p1.setName("Monica");
System.out.println(p1.getName()); // Monica
System.out.println(p2.getName()); // Paul
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
메모리 구조는 다음과 같다.
