반응형
깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)는 객체 복사의 두 가지 방식으로, 객체를 복사할 때 복사된 객체와 원본 객체 간의 관계를 정의합니다.
얕은 복사 (Shallow Copy)
얕은 복사는 객체의 가장 바깥쪽만 복사하고, 객체 내부의 가변 필드는 참조만 복사합니다. 즉, 원본 객체와 복사된 객체가 동일한 내부 객체를 참조하게 됩니다. 얕은 복사를 수행할 때는 다음과 같은 사항을 고려해야 합니다:
- 간단한 구조: 얕은 복사는 기본적으로 Object.clone() 메서드를 사용하거나 수동으로 필드를 복사합니다.
- 성능: 얕은 복사는 빠르게 수행되지만, 참조가 공유되기 때문에 원본 객체나 복사된 객체의 내부 상태가 변경될 수 있습니다.
예시
class Address {
String city;
public Address(String city) {
this.city = city;
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 얕은 복사 수행
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address.city); // "New York"
System.out.println(person2.address.city); // "New York"
person2.address.city = "Los Angeles";
System.out.println(person1.address.city); // "Los Angeles"
System.out.println(person2.address.city); // "Los Angeles"
}
}
위 예시에서 person1과 person2는 같은 Address 객체를 공유하게 되어, person2의 주소를 변경하면 person1의 주소도 변경됩니다.
깊은 복사 (Deep Copy)
깊은 복사는 객체의 모든 필드를 재귀적으로 복사합니다. 즉, 객체 내부의 가변 필드까지 모두 새로운 객체로 복사됩니다. 이렇게 하면 원본 객체와 복사된 객체가 서로 독립적인 상태를 유지합니다.
- 구조 복잡도: 깊은 복사는 모든 가변 필드를 재귀적으로 복사해야 하므로, 구현이 복잡할 수 있습니다.
- 성능: 깊은 복사는 시간이 더 오래 걸리지만, 원본 객체와 복사된 객체가 독립적이므로 한 객체의 변경이 다른 객체에 영향을 미치지 않습니다.
예시
class Address implements Cloneable {
String city;
public Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new Address(this.city); // 깊은 복사 수행
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) this.address.clone(); // 깊은 복사 수행
return cloned;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("New York");
Person person1 = new Person("John", address);
Person person2 = (Person) person1.clone();
System.out.println(person1.address.city); // "New York"
System.out.println(person2.address.city); // "New York"
person2.address.city = "Los Angeles";
System.out.println(person1.address.city); // "New York"
System.out.println(person2.address.city); // "Los Angeles"
}
}
위 예시에서 person1과 person2는 서로 다른 Address 객체를 가지게 되어, person2의 주소를 변경해도 person1의 주소는 영향을 받지 않습니다.
요약
- 얕은 복사:
- 바깥쪽 객체만 복사하며, 내부의 가변 객체는 참조를 공유.
- 원본 객체와 복사된 객체가 동일한 내부 객체를 참조하게 됨.
- 성능은 좋으나, 한 객체의 변경이 다른 객체에 영향을 미침.
- 깊은 복사:
- 객체의 모든 필드를 재귀적으로 복사.
- 원본 객체와 복사된 객체가 독립적인 내부 객체를 가짐.
- 성능은 낮을 수 있으나, 객체가 완전히 독립적임.
둘 중 어떤 방식을 선택할지는 사용 사례와 성능 요구사항에 따라 다릅니다. 중요한 것은 객체의 불변성, 상태 독립성 등을 고려하여 적절한 복사 방식을 선택하는 것입니다.
반응형
'Programming > Java, Kotlin' 카테고리의 다른 글
[JPA] Entity 간의 관계를 매핑하는 방법, 애너테이션, 속성 (2) | 2024.06.30 |
---|---|
[Java] 커스텀 불변 클래스란? Immutable Class 특징, 예, 이점 (0) | 2024.06.22 |
[Java] ThreadPoolExecutor란? 주요 기능, 사용예시, 장점, 동작 방식 (0) | 2024.06.22 |
[Java] 가비지 컬렉션이란? (가비지가 객체를 수집하는 방법, 사용하는 알고리즘) (0) | 2024.06.22 |
[Java] JVM 이란? 자바 메모리(메모리 각 영역에 객체, 메소드 및 변수를 저장하는 법) (0) | 2024.06.22 |