[Java] Java 에서는 객체 복제를 어떻게 할까?

2025. 4. 26. 14:08·JAVA

 

Java 에서는 객체 복제를 해야 하는 경우가 종종 있습니다.

기존에 있는 원본 데이터에 영향을 안 주고, 같은 객체를 따로 만들어서 쓰기 위해 복제를 합니다.

기존에는 = 연산자를 통해 객체를 복사했지만, 이 방법은 실제로 객체를 복제하는 것이 아니라 원본 객체의 주소만 공유하는 방식입니다. 따라서 복사본을 수정하면 원본 객체에도 영향을 줄 수 있기 때문에, 진짜 복제가 필요할 경우 이제 우리가 알아볼 clone 메소드를 사용합니다.

기존 = 연산자를 사용해서 객체를 복사하면 생기는 결과를 예시로 먼저 보여드리겠습니다.

이런식으로 객체를 복사하고, 복사한 객체를 수정하게 된다면 같은 주소를 참조하고 있기 때문에 기존 객체도 함께 수정이 됩니다.


그러면 이제 객체 복제를 하는 법에 대해 알아보겠습니다.

객체 복제에는 두 가지 방법이 있습니다. 바로 얕은 복제(Shallow Copy) 와 깊은 복제(Deep Copy) 입니다.
얕은 복제는 객체의 주소(참조 값) 까지만 복사하고,
깊은 복제는 객체 내부의 모든 값(필드) 들을 새로운 객체로 완전히 복사합니다.

 

얕은 복제는 객체의 주소까지만 복사하기 때문에, 복사한 객체를 수정하면 원본 객체까지 수정이 됩니다.

제가 위에 작성한 코드들도 얕은 복제에 해당됩니다. 객체의 참조만 복사하고, 원본 객체와 복사된 객체는 동일한 메모리 공간을 참조합니다. 따라서 복사된 객체에서 값을 수정하면 원본 객체도 영향을 받습니다.

 

그렇다면 깊은 복제는 어떻게 사용할까요?

깊은 복제는 객체의 참조를 복사하는 것이 아니라, 객체의 모든 필드를 새로 복사하여 독립적인 객체를 만드는 방식입니다. 즉, 원본 객체와 복사된 객체는 서로 독립적이고, 하나의 객체에서 값을 수정해도 다른 객체에는 영향을 미치지 않습니다.

자바에서 깊은 복제를 구현하려면, 복사하려는 객체의 모든 필드를 새로 생성해야 합니다. 필드가 참조 타입인 경우, 해당 필드도 깊은 복사를 해야 합니다. 아까 코드를 수정해보겠습니다.

먼저 clone() 메소드를 오버라이딩 하여 깊은 복제를 했습니다. clone 메소드는 Object 클래스에 상속 받기 때문에 이런식으로 호출할 수 있습니다. Clone 메소드를 호출하려면 해당 클래스는 Cloneable 인터페이스를 구현해야 합니다. 이 인터페이스는 자바에서 객체 복제를 허용하는 역할을 하는데, 해당 인터페이스를 구현하지 않으면 CloneNotSupportedException 이 발생하게 됩니다.

그래서 저는 깊은 복제하는 메소드에 예외처리를 해놨습니다.

주소 클래스도 동일하게 적용

 

이제 메인 클래스입니다.

Address 와 Person 클래스의 객체를 생성했고, clone 메소드를 사용하기 위해 try catch 문으로 CloneNotSupportedException 
예외 처리를 해놨습니다. 

Person deepCopiedPerson = (Person) original.clone();

이제 클론 메소드를 사용해서 deepCopiedPerson 이라는 객체를 생성했는데, clone 메소드가 Object 클래스에 정의되어 있기 때문에, 우리는 Person 타입을 반환해야 하기 때문에 반환값을 Person 타입으로 바꿔주기 위해 다운캐스팅을 했습니다.

이제 deepCopiedPerson 객체의 값을 수정해주고 출력해주면 원본 객체는 수정되지 않고, 깊은 복제를 한 deepCopiedPerson 객체만 수정돼서 출력 됩니다.

💡 실제 웹 개발에서 깊은 복제가 유용할 수 있는 경우

웹 애플리케이션을 개발하면서 HttpSession을 자주 사용하게 됩니다. 예를 들어 로그인한 사용자의 정보를 세션에 저장하고, 다양한 로직에서 이를 꺼내서 사용하게 되죠. 그런데 이 세션 객체를 실수로 직접 수정하게 되면, 애플리케이션 전체에서 공유 중인 세션 상태가 의도치 않게 변경될 위험이 있습니다.

이럴 때 저는 깊은 복제를 활용해 원본 세션 객체를 보호하는 방법을 떠올렸습니다.

예를 들어, 세션에서 꺼낸 사용자 객체를 그대로 수정하기보다는, 먼저 깊은 복제를 통해 새로운 객체로 분리한 뒤 그 객체를 조작하는 식으로 코드를 짠다면, 원본 세션 값은 그대로 유지되면서 안정적으로 로직을 처리할 수 있을 것이라 생각했습니다.

 

✍️ 마무리

이번 글에서는 자바에서 얕은 복제(Shallow Copy)와 깊은 복제(Deep Copy)의 차이를 이해하고, clone() 메서드를 활용해 깊은 복제를 구현하는 방법까지 알아보았습니다.

중요한 점은, 단순히 = 연산자를 사용하는 경우는 얕은 복제이기 때문에 참조 값만 복사되어 원본 객체와 복제본이 서로 영향을 주게 됩니다. 반면 clone() 메서드를 오버라이드하고 참조 타입 필드까지 복제하도록 구현하면, 독립적인 객체를 만들 수 있는 깊은 복제가 가능합니다.

 

 

 

'JAVA' 카테고리의 다른 글

POJO란 무엇일까?  (1) 2025.05.21
[Java] Jave 의 컬렉션 프레임워크는 무엇일까?  (2) 2025.04.23
[Java] Generics은 무엇이고 왜 사용할까?  (0) 2025.04.22
[Java] 인터페이스를 사용하는 이유는 무엇일까?  (0) 2025.04.21
[Java] GC(가비지 컬렉션)이란?  (1) 2025.04.21
'JAVA' 카테고리의 다른 글
  • POJO란 무엇일까?
  • [Java] Jave 의 컬렉션 프레임워크는 무엇일까?
  • [Java] Generics은 무엇이고 왜 사용할까?
  • [Java] 인터페이스를 사용하는 이유는 무엇일까?
동준1234
동준1234
공부 기록
  • 동준1234
    dongjundev
    동준1234
  • 전체
    오늘
    어제
  • GitHub
    • 분류 전체보기 (150)
      • 일상 (1)
      • 복습 및 회고록 (26)
      • Spring (17)
      • JAVA (32)
      • kubernetes (1)
      • Front-End (13)
      • Server (11)
      • SQL (20)
        • JDBC (1)
      • 자격증 (7)
        • 정보처리기사 필기 준비 (6)
        • 정보처리기사 실기 준비 (0)
        • SQLD (1)
      • project (18)
        • 백준 및 코딩테스트 공부 (6)
        • 대학교 캡스톤 디자인 (6)
        • 4학년 캡스톤 디자인 및 전시회 (3)
      • 네트워크 (3)
      • AI 머신러닝 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    react
    프론트
    jQuery
    개발자
    JavaScript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
동준1234
[Java] Java 에서는 객체 복제를 어떻게 할까?
상단으로

티스토리툴바