티스토리 뷰

Backend/Java

Unmodifiable Collection

ellie.strong 2022. 2. 28. 15:56
728x90

이전에 우테코 크루들과 “final이 보장하는 불변은 어디까지인지?”에 대해 얘기를 나누었을 때, 어떤 크루가 본인은 컬렉션의 불변을 보장해야할 때는 unmodifiable 상태로 명시한다는 이야기를 했었다. "unmodifiable" 사실 Java 인생에서 처음 들어보는 단어였다. 그래서 그런지 뭔가 머릿속에서 휘발되고 말았는데.. "일급 컬렉션(First Class Collection)"에 대해 학습을 하다보니 다시 "객체의 불변"에 대한 내용이 나왔고, 불변과 관련해서 컬렉션에서는 unmodifiable이라는 상태를 지원한다는 것을 알게되었다. 

 

Unmodifiable Collection

Unmodifiable Collection은 수정할 수 없는 컬렉션임을 뜻하며, "Read-Only" 용도로만 사용할 수 있다.

외부에서 해당 컬렉션의 내용 변경을 시도할 경우 "UnsupportedOperationException"을 발생 시켜 이를 막는다. 

따라서, 컬렉션 내부 값의 안전성이 보장되어야 한다면 Unmodifiable Collection을 사용해주는 것이 좋다. 

 

✅ final : 객체의 재할당을 막는다.

 Unmodifiable Collection : 컬렉션의 내용 수정을 막는다. 

 

로또미션의 Lotto 클래스에서 Lotto의 모든 값을 정수형 리스트로 반환하는 메서드를 이용해 받아온 리스트를 "final"로 선언해도 해당 리스트는 다음과 같이 그 내용이 수정될 수 있다. 

public List<Integer> getIntValues() {
    return numbers.stream()
            .map(LottoNumber::getNumber)
            .collect(Collectors.toList());
}
void test() {
    final List<Integer> lottoIntValues = lotto.getIntValues();
    lottoIntValues.add(1);
}

 

하지만 해당 메서드에 unmodifiable을 적용하여 리턴하면

set(), add() 등 수정하려는 메서드를 호출했을때 "UnsupportedOperationException"을 발생시킨다. 

public List<Integer> getIntValues() {
    return numbers.stream()
            .map(LottoNumber::getNumber)
            .collect(Collectors.toUnmodifiableList());
}
void test() {
    List<Integer> lottoIntValues = lotto.getIntValues();
    lottoIntValues.add(1);
}

 

이후 이와 관련하여 Immutable, 방어적 복사에 대한 학습이 필요하다고 생각된다. 

 

Ref.

https://soft.plusblog.co.kr/71

https://tecoble.techcourse.co.kr/post/2021-04-26-defensive-copy-vs-unmodifiable/

 

728x90
댓글
공지사항
최근에 올라온 글