SW/Java

Java에서 객체 복사하기: 깊은 복사와 얕은 복사 완벽 가이드

얇은생각 2024. 6. 25. 07:30
반응형

Java 프로그래밍에서 객체를 복사해야 하는 상황이 종종 발생합니다. 그러나 모든 복사가 동일한 것은 아닙니다. 실제로 객체를 복사하는 두 가지 주요 방법이 있습니다: 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy). 이 글에서는 이 두 가지 개념을 탐구하고, 이를 사용하여 객체를 복사하는 방법을 쉽게 이해할 수 있도록 예제를 통해 설명하겠습니다.

 

 

Java에서 객체 복사하기: 깊은 복사와 얕은 복사 완벽 가이드

 

 

깊은 복사란 무엇인가?

깊은 복사는 원본 객체의 완전히 새로운 복사본을 만드는 것을 의미합니다. , 원본 객체가 포함하고 있는 모든 중첩된 객체들도 모두 새로 복사하는 것입니다. 이는 마치 각 도형의 세부 사항까지 포함한 사본을 만드는 것과 같습니다. 깊은 복사를 통해 생성된 객체는 원본 객체와 완전히 독립적이며, 어느 한 쪽에 변경을 가해도 다른 쪽에는 영향을 미치지 않습니다.

 

 

얕은 복사란 무엇인가?

반면 얕은 복사는 그림과 그 틀을 복사하는 것과 비슷합니다. 새로운 틀은 얻을 수 있지만, 그림 자체는 동일하게 남아 있습니다. 마찬가지로, 얕은 복사는 새로운 객체를 생성하지만, 여전히 원본 객체와 중첩된 객체를 공유합니다. 따라서, 복사된 객체의 중첩된 객체에 변경을 가하면 원본 객체에도 영향을 미치게 됩니다.

 

 

예제로 이해하기: 도형 복사

이제 Circle이라는 클래스와 그 중심을 나타내는 Point라는 중첩된 객체를 포함하는 예제를 통해 깊은 복사와 얕은 복사가 어떻게 작동하는지 살펴보겠습니다.

public class Circle {
   public Point center;
   public int radius;

   public Circle(Point center, int radius) {
       this.center = center;
       this.radius = radius;
   }
}

public class Point {
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

 

 

얕은 복사 생성하기

얕은 복사를 위해서는 중첩된 객체에 대한 참조만을 복사하면 됩니다. 아래 예제를 참고하세요.

public Circle shallowCopyCircle(Circle original) {
    return new Circle(original.center, original.radius);
}

 

 

이 메서드는 original 객체의 center 참조를 복사하여 새로운 Circle 객체를 생성합니다. 이로 인해 복사된 객체와 원본 객체는 동일한 Point 객체를 공유하게 됩니다.

깊은 복사 생성하기

깊은 복사를 위해서는 Circle 객체와 그 내부의 Point 객체를 모두 새로 생성해야 합니다.

public Circle deepCopyCircle(Circle original) {
    Point copiedPoint = new Point(original.center.x, original.center.y);
    return new Circle(copiedPoint, original.radius);
}

 

이 메서드는 original 객체의 center 값을 기반으로 새로운 Point 객체를 생성하고, 이를 사용하여 새로운 Circle 객체를 생성합니다. 결과적으로, 복사된 객체는 원본 객체와 완전히 독립적입니다.

 

 

복사 유틸리티 클래스 생성하기

다음은 객체 복사 메서드를 포함한 간단한 유틸리티 클래스입니다.

public class CopyUtil {
    public Circle deepCopyCircle(Circle original) {
        Point copiedPoint = new Point(original.center.x, original.center.y);
        return new Circle(copiedPoint, original.radius);
    }

    public Circle shallowCopyCircle(Circle original) {
        return new Circle(original.center, original.radius);
    }
}

 

 

단위 테스트 작성하기

깊은 복사와 얕은 복사 메서드가 제대로 작동하는지 확인하기 위해 간단한 단위 테스트를 작성할 수 있습니다.

public class ShallowAndDeepCopyUnitTest {

    @Test
    public void givenCircle_whenDeepCopy_thenDifferentObjects() {
        CopyUtil util = new CopyUtil();
        Point center = new Point(3, 5);
        Circle original = new Circle(center, 10);
        Circle copied = util.deepCopyCircle(original);
        assertNotSame(original, copied);
        assertNotSame(original.center, copied.center);
    }

    @Test
    public void givenCircle_whenShallowCopy_thenSameCenter() {
        CopyUtil util = new CopyUtil();
        Point center = new Point(7, 9);
        Circle original = new Circle(center, 15);
        Circle copied = util.shallowCopyCircle(original);
        assertNotSame(original, copied);
        assertSame(original.center, copied.center);
    }
}

 

 

이 테스트는 deepCopyCircle 메서드가 원본과 완전히 독립적인 객체를 생성하는지, shallowCopyCircle 메서드가 원본과 중첩된 객체를 공유하는지 확인합니다.

 

 

결론

Java에서 객체를 깊은 복사와 얕은 복사로 복사하는 것은 마치 그림과 그 틀을 복사하는 것과 같습니다. 깊은 복사는 모든 것을 복제하는 것이며, 얕은 복사는 새로운 틀을 만들되 그림은 동일하게 유지하는 것입니다. 이 개념을 이해하고 Java 프로그램에 적용하면 객체를 필요에 따라 올바르게 복사할 수 있습니다. 원형, 사각형 또는 다른 어떤 객체든지 간에, 복사 방법을 이해하면 Java 프로그래밍이 더욱 매끄럽고 효율적으로 이루어질 것입니다.

추가적으로, 객체 복사를 할 때는 각 객체의 상태와 복사의 용도를 고려해야 합니다. 복사된 객체가 원본 객체와 독립적이어야 하는지, 아니면 일부 속성을 공유해도 되는지에 따라 적절한 복사 방법을 선택하는 것이 중요합니다. 이를 통해 코드의 안정성과 예측 가능성을 높일 수 있습니다.

반응형