백엔드 면접 질문

얕은 복사와 깊은 복사에 대해서 설명해주세요.

Griotold 2024. 12. 4. 10:58

1. 얕은 복사(Shallow Copy)

 

  • 얕은 복사는 객체의 최상위 수준 필드만 복사한다.
  • 원시 타입 필드는 값이 복사되지만, 참조 타입 필드는 참조만 복사된다.
  • 새로운 객체를 생성하지만 내부 객체의 참조는 원본 객체와 공유한다.

 

1 - 1. 예시 - 얕은 복사

public class ShallowCopyExample {
    public static void main(String[] args) {
        int[] originalArray = {1, 2, 3, 4, 5};
        Product original = new Product("Laptop", 1000, originalArray);
        Product copy = original.shallowCopy();

        System.out.println("Original: " + original);
        System.out.println("Copy: " + copy);

        // 내부 배열 수정
        originalArray[0] = 10;

        System.out.println("After modification:");
        System.out.println("Original: " + original);
        System.out.println("Copy: " + copy);
    }
}

class Product implements Cloneable {
    private String name;
    private double price;
    private int[] data;

    // 생성자, getter, setter 생략

    public Product shallowCopy() {
        try {
            return (Product) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    @Override
    public String toString() {
        return "Product{name='" + name + "', price=" + price + ", data=" + Arrays.toString(data) + '}';
    }
}

 

Object의 clone() 메서드를 활용해서 복사해준다.

Cloneable 인터페이스를 구현하지 않으면 CloneNotSupportedException이 발생한다.

얕은 복사 방식이다.

 

출력

Original: Product{name='Laptop', price=1000.0, data=[1, 2, 3, 4, 5]}
Copy: Product{name='Laptop', price=1000.0, data=[1, 2, 3, 4, 5]}

After modification:
Original: Product{name='Laptop', price=1000.0, data=[10, 2, 3, 4, 5]}
Copy: Product{name='Laptop', price=1000.0, data=[10, 2, 3, 4, 5]}

 

originalArray의 요소를 변경했는데 복사된 객체의 배열도 같이 변경되었음을 확인할 수 있다.

 

2. 깊은 복사(Deep Copy)

 

  • 깊은 복사는 객체의 모든 수준의 필드를 새로운 메모리 공간에 복사한다.
  • 내부 객체도 새로 생성되어 복사된다.
  • 복사된 객체와 원본 객체는 완전히 독립적이다.

 

2 - 1. 예시 - 깊은 복사

public class DeepCopyExample {
    public static void main(String[] args) {
        int[] originalArray = {1, 2, 3, 4, 5};
        Product original = new Product("Laptop", 1000, originalArray);
        Product copy = original.deepCopy();

        System.out.println("Original: " + original);
        System.out.println("Copy: " + copy);

        // 내부 배열 수정
        originalArray[0] = 10;

        System.out.println("After modification:");
        System.out.println("Original: " + original);
        System.out.println("Copy: " + copy);
    }
}

class Product implements Cloneable {
    private String name;
    private double price;
    private int[] data;

    // 생성자, getter, setter 생략

    public Product deepCopy() {
        Product copy = new Product(this.name, this.price, null);
        if (this.data != null) {
            copy.data = new int[this.data.length];
            System.arraycopy(this.data, 0, copy.data, 0, this.data.length);
        }
        return copy;
    }

    @Override
    public String toString() {
        return "Product{name='" + name + "', price=" + price + ", data=" + Arrays.toString(data) + '}';
    }
}

 

data 배열에는 새로운 배열을 생성하여 System.arraycopy() 로 배열 내용을 복사해주고 있다.

새로운 메모리 주소에 할당 되기 때문에 깊은 복사인 것이다.

 

출력 결과

Original: Product{name='Laptop', price=1000.0, data=[1, 2, 3, 4, 5]}
Copy: Product{name='Laptop', price=1000.0, data=[1, 2, 3, 4, 5]}

After modification:
Original: Product{name='Laptop', price=1000.0, data=[10, 2, 3, 4, 5]}
Copy: Product{name='Laptop', price=1000.0, data=[1, 2, 3, 4, 5]}

 

originalArray의 요소를 변경했지만, 복사된 객체의 배열은 변경되지 않았다.

 

References

https://www.maeil-mail.kr/question/62