얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)

Kkd·2024년 11월 28일

매일메일 개념정리

목록 보기
11/93

Java에서 객체를 복사하는 방법은 크게 얕은 복사 (Shallow Copy)깊은 복사 (Deep Copy)로 나뉩니다. 이 두 방법은 객체의 참조 및 데이터 복사 방식에 차이가 있습니다.


1. 얕은 복사 (Shallow 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도 영향을 받음
    }
}

2. 깊은 복사 (Deep Copy)

  • 개념
    객체의 필드 값을 재귀적으로 복사하여, 원본 객체와 복사된 객체가 독립적으로 존재하도록 만듭니다.
    참조형 필드도 별도의 새로운 객체를 생성해 복사됩니다.

  • 특징

    • 원본 객체와 복사된 객체가 완전히 독립적.
    • 원본 객체를 수정해도 복사된 객체에는 영향을 미치지 않음.
    • 직접 구현하거나, 외부 라이브러리(예: Apache Commons Lang의 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())복잡 (직접 구현 필요)
영향 관계원본 수정 시 복사본에 영향 있음원본 수정 시 복사본에 영향 없음

주의할 점

  1. Object.clone()을 사용할 때, 클래스는 반드시 Cloneable 인터페이스를 구현해야 합니다.
  2. 깊은 복사를 직접 구현하는 경우, 참조형 필드가 많을수록 구현이 복잡해질 수 있습니다.
  3. 필요에 따라 Serialization을 활용하거나 라이브러리를 사용하는 것이 편리할 수 있습니다.
profile
🌱

0개의 댓글