Unmodifiable
Collection.unmodifiableList()
같은 메소드에서 리턴되는 레퍼런스는 수정 메소드를 호출 할 수 없다. 여기서 수정 메서드
라 함은 add(), set(), addAll() 등을 의미한다. 만약 호출하게 된다면 UnsupportedOperationException
이 발생한다.
하지만 원본 리스트 자체가 수정되지 않도록 보장해주진 않는다. 또한 여기서 원본 리스트를 수정하면 unmodifiableList
자체도 동일하게 수정된다.
예제를 살펴보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String []args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> unmodifialbeList = Collections.unmodifiableList(list);
try {
unmodifialbeList.add(4);
System.out.println("cannot be reached here");
} catch (UnsupportedOperationException e) {
System.out.println("Cannot modify unmodifialbe list");
}
list.add(4);
System.out.println(unmodifialbeList.get(3));
}
}
결과는 아래 이미지와 같이 unmodifialbeList.add()
를 호출할 경우 UnsupportedOperationException
이 발생하는 것을 확인하실 수 있다. 그리고 원본 list에는 정상적으로 list.add()
가 동작한 것을 확인하실 수 있으며 unmodifialbeList
자체도 동일하게 4가 추가된 것을 확인하실 수 있다.
Immutable(불변) vs Unmodifiable Collection
만약 객체의 상태가 Immutable이라 한다면 무조건 수정할 수 없어야 한다. unmodifiableList는 원본 리스트를 변경함으로써 unmodifialbeList
를 수정할 수 있기 때문에 Immutable을 만족하지 않는다.
기존에 존재하는 컬렉션을 Immutable로 만들기 위해서는 기존 컬렉션의 데이터를 새로운 컬렉션으로 복사한 다음, 새로운 컬렉션으로의 수정(modify) 접근을 제한하는게 일반적이다.
예를들어
1
List<String> immutableList = Collections.unmodifiableList(new ArrayList<String>(list));
원본 컬렉션인 list의 내용을 복사해서 unmodifiableList를 만들기 때문에 여기서 리턴되는 List는 immutable
이다.