결론부터 말하자면, Java에서 배열 자체의 요소를 직접 불변(immutable)으로 만드는 것은 불가능합니다. 배열은 한 번 생성되면 내장된 기능만으로는 요소의 수정을 완전히 차단할 수 없습니다.
하지만 java.util.Collections 클래스의 unmodifiableList() 메서드를 활용하면 이 문제를 우회하여 해결할 수 있습니다. 이 메서드는 List 인터페이스를 구현한 객체를 매개변수로 받아, 해당 리스트의 읽기 전용(read-only) 뷰를 반환합니다. 반환된 리스트에 요소를 추가하거나 수정하려고 시도하면 UnsupportedOperationException 예외가 발생합니다.
또한 Arrays 클래스의 asList() 메서드는 배열을 매개변수로 받아 List 객체로 변환해 주므로, 두 메서드를 조합하면 배열 기반의 불변 리스트를 손쉽게 만들 수 있습니다.
배열을 불변 리스트로 변환하는 절차
불변으로 만들고자 하는 배열을 준비합니다.
asList() 메서드를 사용하여 배열을 List 객체로 변환합니다.
변환된 리스트를 unmodifiableList() 메서드에 전달하여 읽기 전용 리스트를 얻습니다.
예제 코드
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class UnmodifiableExample {
public static void main(String args[]) {
// 문자열 배열 생성
String strArray[] = {"Raju", "Rama", "Rahman", "Rachel", "Ranbhir", "Rangan"};
// 문자열 배열을 List 객체로 변환
List<String> list = Arrays.asList(strArray);
// List 객체를 불변(읽기 전용)으로 변환
List<String> immutable = Collections.unmodifiableList(list);
System.out.println(immutable);
// 불변 리스트에 요소 추가 시도 → 예외 발생
immutable.add("komala");
}
}실행 결과
[Raju, Rama, Rahman, Rachel, Ranbhir, Rangan] Exception in thread "main" java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.add(Unknown Source) at September19.UnmodifiableExample.main(UnmodifiableExample.java:19)
위 실행 결과를 보면, 리스트 출력은 정상적으로 수행되지만 add() 메서드로 새로운 요소를 추가하려는 순간 UnsupportedOperationException이 발생하는 것을 확인할 수 있습니다. 이것이 바로 unmodifiableList()가 제공하는 보호 장치입니다.
참고: Java 9 이상에서는 List.of() 사용 권장
Java 9부터는 List.of() 팩토리 메서드를 사용하면 별도의 변환 과정 없이 처음부터 불변 리스트를 생성할 수 있어 더욱 간편합니다.
List<String> immutable = List.of("Raju", "Rama", "Rahman", "Rachel", "Ranbhir", "Rangan");다만 주의할 점이 있습니다. unmodifiableList()는 원본 리스트에 대한 뷰(view)일 뿐이므로, 원본 리스트가 수정되면 뷰에도 그 변경 사항이 반영됩니다. 반면 List.of()로 생성한 리스트는 완전히 독립적인 불변 객체입니다. 따라서 원본 데이터의 변경 가능성이 있다면 List.of()를 사용하는 것이 더 안전합니다.