본문 바로가기
Lang & Framework

가변 객체의 위험성

by . 2021. 8. 29.

가변 객체를 사용하면 원본이 수정될 수 있기 때문에 위험합니다. 또한 이를 동시에 여러 곳에서 수정하게 되면 데이터의 변경을 추적하는 것이 쉽지 않습니다. 아래 예시는 가변 클래스 Numbers에 숫자를 넣고 값을 변경했을 때 원본 리스트를 확인하는 것입니다.

 

 

 

 

 

 

controller 객체의 첫 번째 값을 100으로, 두 번째 값 200으로 수정했기 때문에 당연히 일치하지 않습니다. 

 

 

 

 

 

 

 

하지만 numbers의 결과를 확인해보면 이 또한 값이 바뀌어있습니다. 이는 controller가 numbers와 같은 값을 참조했기 때문입니다. 

 

 

 

 

 

 

 

 

이처럼 참조값을 공유했을 때 한 쪽 데이터를 수정하면 원본객체에까지 영향이 가게 됩니다. 이를 막기 위해서는 방어적 복사를 통해 값을 복사하거나 새로운 객체를 만들어 참조를 끊어야 합니다. 

 

 

 

 

 

 

 

 

3. 방법


방어적 복사를 하기 위한 몇 가지 방법. 

 

 

 

 

 

3-1. Collections.unmodifiableList

Collections.unmodifiableList는 Collections 인터페이스에 존재하는 리스트로 리스트 내부에 수정을 가하면 예외를 발생시킨다. 언뜻 보기에 이를 통해 불변 리스트를 생성할 수 있을 것 같지만 사실 그렇지 않다. 

 

 

 

 

 

 

이는 기존 리스트를의 내부 인자 주소를 공유하고 있기 때문에 원본 리스트를 수정하면 Collections로 만든 unmodifiable 리스트에도 수정이 가해진다. 즉, 새로 만든 리스트를 수정하면 오류가 발생하지만 원본을 수정했을 경우 새로 생성된 리스트도 변화가 발생한다. 

 

 

 

 

 

 

 

 

 

3-2. List.copyOf( )

 

 

 

 

 

 

4. 불변객체의 장단점


장점

      - 객체의 신뢰도가 높아집니다. 객체가 한번 생성되어서 그게 변하지 않는다면 transaction 내에서 그 객체가 변하지 않기에 이를

         믿고 쓸 수 있기 때문입니다. 따라서 생성자, 접근메소드에 대한 방어적 복사를 할 필요없습니다.

      - 멀티스레드 환경에서 동기화 처리없이 객체를 공유할 수 있습니다.

단점

       - 객체가 가지는 값마다 새로운 객체가 필요하기 때문에 메모리 누수와 새로운 객체를 계속 생성해야하기 때문에 성능저하를 발생시킬

         수 있습니다.

 

 

 

 

 

 

 

 

 

'Lang & Framework' 카테고리의 다른 글

Validation  (0) 2021.02.09