코딩은 내일부터

[우테코] 우아한테크코스 생존기 (1)(방어적 복사) 본문

우아한 테크 코스(우테코)/우테코 공부

[우테코] 우아한테크코스 생존기 (1)(방어적 복사)

zl존 비버 2023. 2. 27. 15:05
728x90

같은방어 다른 느낌..

우리가 불변성을 보장해줘야 할 때 꼭 알아야 할 개념이 얕은 복사, 깊은 복사, 방어적 복사이다.

 

 

 

얕은 복사란 무엇인지

  • 객체를 복사할 때, 해당 객체만 복사하여 객체를 생성한다.
  • 복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조되어 메모리 주소의 값이 변경되면 원본 객체 복사 객체의 인스턴스 변수 값은 같이 변경된다.

 

깊은 복사란 무엇인지

  • 객체를 복사 때, 해당 객체와 인스턴스 변수까지 복사한다.
  • 전부를 복사하여 주소에 담기 때문에 참조를 공유하지 않는다.

 

 

여기서 깊은 복사와 방어적 복사는 비슷하지않다.

 

이유는 방어적복사는 컬렉션의 겉에 있는 포장만 불변을 보장하고 안에있는 객체는 같기 때문에 깊은 복사라할 없다.

방어적 복사에는new, copyof, unmodifiable이 있는데

 

 

 

new

new를 이용하여 객체를 복사하면 참조되는 주소가 달라져 원본에서 값이 변경되면 복사된 객체에서는 변화가 안 일어나는 것 을 볼 수 있습니다.

하지만 복사된 객체에서는 add, remove 등등 불변성을 보장할 수 없다는 단점이 있습니다.

 

copyOf

copyof는 복사된 컬랙션의 불변성을 보장하고 원본 컬랙션과의 참조값을 변경하여 원본 컬랙션에서 add,remove 등 과같은 행위가 일어날 시 copyof 된 컬랙션에서는 값의 변화가 없다는 장점이 있습니다.

 

 

unmodifiable

unmodifiable은 복사된 컬랙션의 불변성을 보장하지만 copyof와 다른 점은 원본 컬랙션에서 변화가 일어나면 unmodifiable를 사용해 복사된 컬랙션에서도 변화가 일어납니다.

                         l         불변성        ㅣ        원본과의 연결        ㅣ                  

new.                  l            X             l                X                    l

copyOf              l            O             l                X                    l

unmodifiable.  l             O             l                O                    l

 

하지만 new 와 copyOf,unmodifiable로 복사한 객체 안에 있는 원소의 참조값은 똑같기 때문에 객체 변화가 일어날 시 복사된 원소에도 값이 변화된다.

 

 

 

 

CopyOf와unmodifiableList은 언제 사용해야 하는가

 

copyOf 컬랙션이 불변이고 원본 컬렉션과의 참조를 끊는다.

unmodifiable 또한 불변이고 copyof 다른점은 원본 컬랙션과의 참조를 끊지 않는다는 것입니다.

이 둘의기능은 비슷하고 어느 상황에 copyOf 쓰는지 unmodifiable 사용하는지 헷갈립니다.

 

객체를 생성하는 시점, 객체를 조회하는 시점에서 생각해보면 조금 편하게 접근할 있습니다.

먼저 객체를 생성하는 시점에서 final 넘겨준다 해도 불변성을 보장할 없습니다.

그렇기 때문에 방어적 복사를 사용해 불변성을 보장해줄 있습니다.

 

객체를 조회하는 시점에서 보면 조회를 또한

불변성을 보장해 주기 위해 수정 불가능한 리스트를 넘겨줍니다.

여기서 위의 두 시점에서 copyOf와 unmodifiable을 사용할지 고민을 하게 됩니다.

 

전부다 copyof나 unmodifiable 사용해서 통일해 주면 안 되나? 생각하는데

생각은 조회만 굳이 copyOf 사용한다는게 비효율적이라고 생각해서 내린 결론은

 

불변을 보장해줘야하는 객체를 생성할 때는 copyOf 원본과의 연결을 끊어 불변성을 보장하고

getter에서 조회의 용도로 사용할 때는 unmodifiable 사용하는 적절하다고 생각했습니다.