[Java] 방어적 복사에 대한 고찰

김민수 / Minsu Kim·2024년 2월 25일
0

[Java]에 대한 고찰

목록 보기
4/7
post-thumbnail

⭐️ 방어적 복사란 무엇인가?

방어적 복사란 객체를 복사하여 새로운 객체를 생성하는 것을 말한다.
이렇게 복사된 객체는 원본 객체와 독립적으로 존재하며, 원본 객체의 상태 변경이 복사 객체에 영향을 주지 않는다.

⭐️ 방어적 복사를 왜 사용하지?

객체의 불변성과 안정성을 위해 사용한다.
이를 통해 예상치 못한 상태 변화나 외부에서의 객체 변경을 방지할 수 있다.

⭐️ 방어적 복사, 얕은 복사, 깊은 복사를 알아보자!

  • 방어적 복사
    • 원본 객체의 복사본을 만드는 것이다.
    • 내부 객체는 같은 주소 값을 참조한다.
    • 복사한 외부 객체를 변경해도 원본 객체를 변경되지 않는다.
    • 원본 객체가 변경되면 복사된 객체가 변경된다.
  • 얕은 복사
    • 원본 객체의 주소 값을 참조하여 복사하는 것이다.
    • 원본 객체를 수정하면 복사 객체도 수정된다.
    • 복사 객체를 수정하면 원본 객체도 수정된다.
  • 깊은 복사
    • 원본 객체의 모든 값을 복사해서 원본과 완전히 독립적이게 복사하는 것.
    • 서로 내부나 외부가 변경되어도 복사본에 영향을 주지 않는다.

⭐️ 방어적 복사와 불변 리스트를 알아보자!

🍀 new ArrayList()

방어적 복사는 일반적으로 new ArrayList에 원본을 담아서 복사하는 방법을 사용한다. 원본이 변경되어도 복사본이 변경되지 않는 장점이 있다. 하지만 복사본이 변경될 수 있다는 단점이 있다.

🍀 Collections.unmodifiableList()

불변 리스트는 얕은 복사를 한다. 즉, 원본과 같은 주소 값을 참조한다.
원본이 변경되면 복사본도 변경된다는 단점이 있다.
하지만 복사본을 수정할 경우 런타임 에러가 발생하여 수정을 막는 장점이 있다.

🍀 List.copyOf()

List.copyOf는 원본과의 참조를 끊는 복사본을 만든다.
원본 수정이 복사본에 영향을 주지 않는 장점이 있다.
또한 불변 리스트와 마찬가지로 복사본을 수정하면 런타임 에러가 발생하는 장점도 가진다.

⭐️ 아쉬운 점을 알아보자!

원본을 방어적 복사를 해도 내부에 있는 객체는 같은 주소 값을 가지기 때문에 원본 내부의 객체들이 변경되면 복사본 내부의 객체들도 변경된다.

예를 들어, 다음과 같은 상황이다.

List<Car> cars1 = ...
List<Car> cars2 = new ArrayList<>(cars1);
cars1.get(0).setName("B");

내부의 값도 복사하기 위해서는 clone이나 복사 생성자를 만들어서 사용해야한다.

⭐️ 결론

방어적 복사는 어디에 사용될까?

생성자의 인자로 컬렉션을 받을 경우

  • 외부에서 전달받은 것이 변한다고 내부의 값이 변하면 안되므로 방어적 복사를 사용한다.

객체에서 컬렉션을 반환할 경우

  • 객체 내부에서 값이 변했다고 반환된 값이 변하게하고 싶지 않다면 방어적 복사
  • 상관이 없고, 복사에 대한 비용이 크다면 불변 리스트를 사용한다.
profile
https://alstn113.tistory.com

0개의 댓글