얕은 복사

객체를 복사할 때 최상위 객체만 새로 만들고, 내부에 참조하는 객체들은 원본과 같은 주소를 공유하는 방식입니다.

쉽게 말해, 껍데기만 복사하고 내용물은 원본과 함께 쓰는 것입니다.


Java 예시

import java.util.Arrays;

class Person {
    String name;
    int[] scores;  // 참조 타입

    Person(String name, int[] scores) {
        this.name = name;
        this.scores = scores;
    }

    // 얕은 복사
    Person shallowCopy() {
        return new Person(this.name, this.scores);  // scores 배열 주소만 복사
    }
}

public class Main {
    public static void main(String[] args) {
        int[] originalScores = {90, 85, 88};
        Person original = new Person("김철수", originalScores);

        // 얕은 복사 수행
        Person copied = original.shallowCopy();

        // 복사본의 scores 수정
        copied.scores[0] = 100;

        // 원본도 변경됨!
        System.out.println("원본 scores: " + Arrays.toString(original.scores));
        // 출력: [100, 85, 88]

        System.out.println("복사본 scores: " + Arrays.toString(copied.scores));
        // 출력: [100, 85, 88]
    }
}

메모리 구조

[원본 Person]              [복사본 Person]
┌─────────────┐           ┌─────────────┐
│ name: "김철수"│           │ name: "김철수"│  ← 새로운 String (불변이라 상관없음)
│ scores: ────┼───┐   ┌───┼─ scores     │
└─────────────┘   │   │   └─────────────┘
                  ▼   ▼
              ┌─────────────┐
              │ [100, 85, 88] │  ← 같은 배열을 공유!
              └─────────────┘

깊은 복사와 비교

구분얕은 복사깊은 복사
내부 객체주소 공유새로 생성
원본 영향서로 영향 있음완전 독립
속도빠름느림
// 깊은 복사라면 이렇게
Person deepCopy() {
    int[] newScores = Arrays.copyOf(this.scores, this.scores.length);  // 배열도 새로 생성
    return new Person(this.name, newScores);
}

핵심은 참조 타입 필드가 같은 메모리를 가리키느냐 아니냐입니다. 얕은 복사는 공유하고, 깊은 복사는 완전히 분리합니다.

CSLOG에서 보기