
방어적 복사란 객체를 복사하여 새로운 객체를 생성하는 것을 말한다.
이렇게 복사된 객체는 원본 객체와 독립적으로 존재하며, 원본 객체의 상태 변경이 복사 객체에 영향을 주지 않는다.
객체의 불변성과 안정성을 위해 사용한다.
이를 통해 예상치 못한 상태 변화나 외부에서의 객체 변경을 방지할 수 있다.
방어적 복사는 일반적으로 new ArrayList에 원본을 담아서 복사하는 방법을 사용한다. 원본이 변경되어도 복사본이 변경되지 않는 장점이 있다. 하지만 복사본이 변경될 수 있다는 단점이 있다.
불변 리스트는 얕은 복사를 한다. 즉, 원본과 같은 주소 값을 참조한다.
원본이 변경되면 복사본도 변경된다는 단점이 있다.
하지만 복사본을 수정할 경우 런타임 에러가 발생하여 수정을 막는 장점이 있다.
List.copyOf는 원본과의 참조를 끊는 복사본을 만든다.
원본 수정이 복사본에 영향을 주지 않는 장점이 있다.
또한 불변 리스트와 마찬가지로 복사본을 수정하면 런타임 에러가 발생하는 장점도 가진다.
원본을 방어적 복사를 해도 내부에 있는 객체는 같은 주소 값을 가지기 때문에 원본 내부의 객체들이 변경되면 복사본 내부의 객체들도 변경된다.
예를 들어, 다음과 같은 상황이다.
List<Car> cars1 = ...
List<Car> cars2 = new ArrayList<>(cars1);
cars1.get(0).setName("B");
내부의 값도 복사하기 위해서는 clone이나 복사 생성자를 만들어서 사용해야한다.
방어적 복사는 어디에 사용될까?
생성자의 인자로 컬렉션을 받을 경우
객체에서 컬렉션을 반환할 경우