방어적 복사에 대해 공부하다가 읽기 전용 List 를 반환하는 unmodifiableList 에 대해서 알게 되었다.
그리고 List.copyOf 또한 읽기 전용 List 를 반환한다
는 것을 알게 되었다. 조금 더 자세히 파악해보자.
public List<Card> getValue() {
return List.copyOf(value);
}
내부 구현 로직을 살펴보니 unmodifiableList 와 똑같이 get 을 제외한 다른 메서드를 호출 할 경우
에러를 던지도록 구현했다. 차이점은 List 원본을 복사한 값을 읽기 전용으로 만든다.
private ImmutableCollections() { }
/**
* The reciprocal of load factor. Given a number of elements
* to store, multiply by this factor to get the table size.
*/
static final intEXPAND_FACTOR= 2;
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
// all mutating methods throw UnsupportedOperationException
@Override public boolean add(E e) { throwuoe(); }
@Override public boolean addAll(Collection<? extends E> c) { throwuoe(); }
@Override public void clear() { throwuoe(); }
@Override public boolean remove(Object o) { throwuoe(); }
@Override public boolean removeAll(Collection<?> c) { throwuoe(); }
@Override public boolean removeIf(Predicate<? super E> filter) { throwuoe(); }
@Override public boolean retainAll(Collection<?> c) { throwuoe(); }
}
// ---------- List Implementations ----------
// make a copy, short-circuiting based on implementation class
@SuppressWarnings("unchecked")
static <E> List<E> listCopy(Collection<? extends E> coll) {
if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
return (List<E>)coll;
} else {
return (List<E>)List.of(coll.toArray());
}
}