CS/필수지식

[매일매일 CS] 얕은 복사와 깊은 복사에 대해

Coding Kitsune 2025. 9. 5. 09:26

 

 

얕은 복사란 ? (Shallow Copy)

 

: 객체 자체만 복사하고, 내부에 포함된 데이터는 그대로 같은 메모리 주소를 공유한다.

에에 따라 원본과 복제본이 같은 하위 객체를 가리킴

(한쪽에서 데이터 수정하면 다른쪽도 영향을 받는다)

 

 

자바로 간단하게 예를 들어보면

 

 

 

class Address {
    String city;
    Address(String city) { this.city = city; }
}

class Person implements Cloneable {
    String name;
    Address address;

    Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 얕은 복사
    }
}

public class example{
    public static void main(String[] args) throws CloneNotSupportedException {
        Address addr = new Address("Seoul");
        Person p1 = new Person("Peter", addr);
        Person p2 = (Person) p1.clone(); // 얕은 복사

        p2.name = "Mike";         // 원시값은 독립적
        p2.address.city = "Busan"; // 참조 객체는 공유됨

        System.out.println(p1.name + ", " + p1.address.city); // Peter, Busan
        System.out.println(p2.name + ", " + p2.address.city); // Mike, Busan
    }
}

 

 

이렇듯 Java에서 Object.clone()을 오버라이드 하면, 객체의 필드 값만 그대로 복사된다.

이에 따라 name은 따로 복사되지만,

address는 공유되므로 p2의 city를 바꾸면 p1도 바뀌게 된다.

 

 

 

 

 

 

깊은 복사란 ? (Deep Copy)

 

: 객체 내부에 포함된 하위 객체까지 재귀적으로 새로 복사하여 원본과 복제본은 완전히 독립적이라 한쪽 수정이 다른 쪽에 영향이 없게 한다.

 

얕은 복사의 예와 비슷하게 들자면

 

 

class Address implements Cloneable {
    String city;
    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;

    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 DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address addr = new Address("Seoul");
        Person p1 = new Person("Peter", addr);
        Person p2 = (Person) p1.clone(); // 깊은 복사

        p2.name = "Mike";
        p2.address.city = "Busan";

        System.out.println(p1.name + ", " + p1.address.city); // Peter, Seoul
        System.out.println(p2.name + ", " + p2.address.city); // Mike, Busan
    }
}

 

 

 

이렇게 깊은 복사로 구현하면 새로 복사한 객체 값의 수정이 원본 객체 값에 영향을 미치지 않고 작업할 수 있다.

 

 

 

정리하자면,

 

 

"

얕은 복사는 객체 자체만 새로 만들고, 내부에 있는 참조는 원본 객체와 같은 메모리 주소를 공유하는 방식입니다.

그래서 복제본의 내부 데이터를 수정하면 원본도 함께 영향을 받습니다.

하지만 깊은 복사는 객체뿐 아니라 내부에 포함된 참조 타입 필드까지 새로 복제하는 방식이라, 완전히 독립적인 상태가 되어 서로 영향을 주지 않습니다.

 

얕은 복사는 메모리 사용량이 적고 속도가 빠른 장점이 있지만, 데이터 일관성을 해칠 수 있고, 복사는 안정적이지만 성능 비용이 커 상황에 따라 선택적으로 사용하는게 중요합니다 !

 

"