Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags more
Archives
Today
Total
관리 메뉴

나만의 개발 로그 | 고민 로그

배열 <깊은 복사, 얕은 복사> 본문

웹 개발

배열 <깊은 복사, 얕은 복사>

ultramancode 2023. 1. 13. 00:37

🧠 개념

✅ 얕은 복사 (Shallow Copy)

  • 객체의 주소(참조값)만 복사
  • 원본과 복사본이 같은 객체를 가리킴
  • 복사본을 수정하면 원본도 함께 변경

= 연산자, .clone() (객체 배열 기준), System.arraycopy() 등


✅ 깊은 복사 (Deep Copy)

  • 객체의 값을 새로운 메모리 공간에 복사
  • 복사본과 원본이 완전히 독립적인 객체
  • 복사본을 변경해도 원본에는 영향 없음

직접 for문 돌리기, 객체 생성 + 복사, 재귀적 복사 등


📌 얕은 복사 예제 (1차원 배열)

int[] arr = {1, 2, 3}; int[] copy = arr; // 얕은 복사 
copy[0] = 99; 
System.out.println(Arrays.toString(arr)); // [99, 2, 3]
→ copy와 arr이 같은 배열을 참조

📌 깊은 복사 예제 (1차원 배열)

int[] arr = {1, 2, 3}; int[] copy = arr.clone(); // 깊은 복사처럼 작동 
copy[0] = 99; 
System.out.println(Arrays.toString(arr)); // [1, 2, 3]

.clone()은 사실 얕은 복사 방식이지만, int[]처럼 원시 타입일 경우 값 복사이기 때문에 깊은 복사처럼 작동


⚠️ 객체 배열에서는 얕은 복사로 동작함

class Person { 
String name; 
	
    Person(String name) { 
	this.name = name; 
	} 
}

Person[] arr = { new Person("Alice"), new Person("Bob") }; 

Person[] copy = arr.clone(); // 얕은 복사 
copy[0].name = "Zoe"; 
System.out.println(arr[0].name); // Zoe ← 원본도 바뀜!
 
 

→ copy[0], arr[0]이 같은 Person 객체를 참조하므로 얕은 복사


✅ 객체 배열의 깊은 복사 방법

Person[] arr = { new Person("Alice"), new Person("Bob") }; 
Person[] copy = new Person[arr.length]; 

for (int i = 0; i < arr.length; i++) { 
copy[i] = new Person(arr[i].name); // 새로운 객체로 복사 
}

copy[0].name = "Zoe"; System.out.println(arr[0].name); // Alice ← 원본은 영향 없음

🧱 2차원 배열: .clone()은 얕은 복사

int[][] arr = { {1, 2, 3}, {4, 5, 6} }; 
int[][] copy = arr.clone(); // 얕은 복사 
copy[0][0] = 99; System.out.println(arr[0][0]); // 99 ← 원본 변경됨

→ 외부 배열만 새 객체고, 내부 배열은 동일한 주소를 공유


🔁 2차원 배열의 깊은 복사 방법

✅ 방법 1: 2중 for문

int[][] arr = { {1, 2, 3}, {4, 5, 6} }; 
int[][] copy = new int[arr.length][arr[0].length]; 
for (int i = 0; i < arr.length; i++) { 
	for (int j = 0; j < arr[i].length; j++) { 
    	copy[i][j] = arr[i][j]; 
    } 
}

✅ 방법 2: System.arraycopy + for

int[][] copy = new int[arr.length][]; 
for (int i = 0; i < arr.length; i++) { 
    copy[i] = new int[arr[i].length]; 
    System.arraycopy(arr[i], 0, copy[i], 0, arr[i].length); 
}

🧾 요약 정리 표


배열 종류 복사 방법 깊은 복사 여부 설명
int[] .clone() ✅ 깊은 복사처럼 작동 값 타입이라 복사됨
Person[] .clone() ❌ 얕은 복사 참조만 복사
Person[] for + new ✅ 깊은 복사 객체 생성 필요
int[][] 2중 for문 ✅ 깊은 복사 내부까지 값 복사
Person[][] 2중 for문 ❌ 얕은 복사 참조만 복사
Person[][] 2중 for + new ✅ 깊은 복사 객체까지 복사 필요

 

 

 


🧠 결론

  • .clone()은 얕은 복사 방식이지만, 원시 타입 배열에서는 깊은 복사처럼 작동
  • 참조 타입 배열이나 다차원 배열에서는 반드시 직접 복사가 필요
  • 얕은 복사는 디버깅이 어려운 사이드 이펙트를 만들 수 있으니 주의

📌 정리

  • 알고리즘 문제에서는 무조건 깊은 복사로 가정하고 for문 사용이 안전
  • .clone()이나 System.arraycopy()는 단일 원시 배열 복사에만 권장
  • 객체 배열을 복사할 땐 copy[i] = new 클래스명(...) 식으로 직접 복사

 

Comments