Skip to content

Latest commit

 

History

History
33 lines (23 loc) · 2.12 KB

36.md

File metadata and controls

33 lines (23 loc) · 2.12 KB

Java 의 Collections.unmodifiableList 같은 API 를 이용해 List 같은 collection 을 변경 불가능하게 만들 수 있습니다. 그렇다면 이 API 를 사용하면 immutability 를 달성할 수 있을까요?

아니요. 불가능합니다. 물론 unmodifiableList와 같은 컬렉션은 add, remove 같은 컬렉션을 변경시키는 메서드들이 모두 막혀 있습니다. (호출하면 예외가 발생합니다.) 하지만 불변은 보장되지 않는데요, 우선 컬렉션의 요소들의 불변이 보장되지 않았기 때문입니다.

예를 들어, unmodifiableList가 A와 B라는 두 객체를 요소로 가지고 있다고 하도록 하겠습니다. unmodifiableList에 C를 새로 추가하거나, 리스트에서 B를 제거할 수는 없어서 불변같아 보이지만 A, B 객체가 불변 객체가 아니어서 A, B 객체의 내부 값이 바뀐다면, 리스트의 불변이 보장되지 않습니다.

불변이 보장되지 않는 또다른 이유로 unmodifiable collection들은 참조가 끊어지지 않는다는 문제가 있습니다. 이로 인해 컬렉션 내부 요소의 불변 뿐 아니라 컬렉션의 변경 불가능함도 깨뜨릴 수 있습니다. 다음의 예시를 보겠습니다.

List<String> origin = new ArrayList<>();
origin.add("오찌");

List<String> unmodifiableList = Collections.unmodifiableList(origin);

origin.add("토르");

assertThat(unmodifiableList).containsOnly("오찌"); // ["오찌", "토르"]여서 실패

unmodifiableList 자체에는 요소를 추가, 삭제 등을 할 수 없지만, unmodifiableList의 원본 리스트에 요소를 추가하거나 삭제를 하게 되면 unmodifiableList에도 그 변경이 반영되게 됩니다. 이는 unmodifiableList를 만들 때, 원본 리스트의 요소를 복사해오는 것이 아니라 원본 리스트의 참조를 저장하기 때문입니다.

static class UnmodifiableList<E> extends UnmodifiableCollection<E> implements List<E> {
    ...
    final List<? extends E> list;

    UnmodifiableList(List<? extends E> list {
        super(list);
        this.list = list;
    }
    ...
}