Java에서 객체를 복사하는 방법은 크게 얕은 복사 (Shallow Copy)와 깊은 복사 (Deep Copy)로 나뉩니다. 이 두 방법은 객체의 참조 및 데이터 복사 방식에 차이가 있습니다.
개념
객체의 참조 값만 복사하는 방식입니다. 원본 객체와 복사된 객체는 동일한 참조를 가지는 필드를 공유하게 됩니다.
기본형 필드나 불변 객체(String 등)는 값이 복사되지만, 참조형 필드는 원본 객체의 참조를 공유합니다.
특징
Object.clone() 메서드를 통해 구현.예제
import java.util.Arrays;
class ShallowCopyExample implements Cloneable {
int[] data;
public ShallowCopyExample(int[] data) {
this.data = data;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 얕은 복사
}
public static void main(String[] args) throws CloneNotSupportedException {
int[] arr = {1, 2, 3};
ShallowCopyExample original = new ShallowCopyExample(arr);
ShallowCopyExample copy = (ShallowCopyExample) original.clone();
System.out.println("Original data: " + Arrays.toString(original.data));
System.out.println("Copy data: " + Arrays.toString(copy.data));
// 원본 배열 수정
original.data[0] = 99;
System.out.println("After modification:");
System.out.println("Original data: " + Arrays.toString(original.data));
System.out.println("Copy data: " + Arrays.toString(copy.data)); // copy도 영향을 받음
}
}
개념
객체의 필드 값을 재귀적으로 복사하여, 원본 객체와 복사된 객체가 독립적으로 존재하도록 만듭니다.
참조형 필드도 별도의 새로운 객체를 생성해 복사됩니다.
특징
SerializationUtils)를 사용.예제
import java.util.Arrays;
class DeepCopyExample implements Cloneable {
int[] data;
public DeepCopyExample(int[] data) {
this.data = data;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 깊은 복사 구현
int[] dataCopy = Arrays.copyOf(this.data, this.data.length); // 배열 복사
return new DeepCopyExample(dataCopy);
}
public static void main(String[] args) throws CloneNotSupportedException {
int[] arr = {1, 2, 3};
DeepCopyExample original = new DeepCopyExample(arr);
DeepCopyExample copy = (DeepCopyExample) original.clone();
System.out.println("Original data: " + Arrays.toString(original.data));
System.out.println("Copy data: " + Arrays.toString(copy.data));
// 원본 배열 수정
original.data[0] = 99;
System.out.println("After modification:");
System.out.println("Original data: " + Arrays.toString(original.data));
System.out.println("Copy data: " + Arrays.toString(copy.data)); // copy는 영향을 받지 않음
}
}
| 구분 | 얕은 복사 | 깊은 복사 |
|---|---|---|
| 복사 대상 | 참조 값만 복사 | 객체 전체 복사 (재귀적) |
| 독립성 | 원본과 복사본이 참조 공유 | 원본과 복사본이 독립적 |
| 수행 속도 | 빠름 | 느림 |
| 구현 난이도 | 쉬움 (Object.clone()) | 복잡 (직접 구현 필요) |
| 영향 관계 | 원본 수정 시 복사본에 영향 있음 | 원본 수정 시 복사본에 영향 없음 |
Object.clone()을 사용할 때, 클래스는 반드시 Cloneable 인터페이스를 구현해야 합니다.Serialization을 활용하거나 라이브러리를 사용하는 것이 편리할 수 있습니다.