How to make collection read only?

2022/07/25

Background

In most requirements, collection needs to be made as read only. There are some ways considered from compile time and run time.

Environments

Compile time

Use <? extends T>

final List<? extends String> list = new ArrayList<>();
list.add("a"); // Compile failed according to PECS rule

But, above usage can not guarantee the read only of collection.

final List<? extends String> list = new ArrayList<>();
System.out.println(list); // []
final List<String> list2 = (List<String>) list;
list2.add("a");
System.out.println(list); // [a]

Run time

Use Arrays.asList()

final List<String> list = Arrays.asList();
list.add("a"); // java.lang.UnsupportedOperationException

Use Collections.singleton()/Collections.singletonList()/Collections.singletonMap()

final Set<String> set = Collections.singleton("a");
set.add("b"); // java.lang.UnsupportedOperationException

final List<String> list = Collections.singletonList("a");
list.add("b"); // java.lang.UnsupportedOperationException

final Map<String, String> map = Collections.singletonMap("a", "1");
map.put("b", "2"); // java.lang.UnsupportedOperationException

Use ImmutableSet.of()/ImmutableList.of()/ImmutableMap.of()

final Set<String> set = ImmutableSet.of("a");
set.add("b"); // java.lang.UnsupportedOperationException

final List<String> list = ImmutableList.of("a");
list.add("b"); // java.lang.UnsupportedOperationException

final Map<String, String> map = ImmutableMap.of("a", "1");
map.put("b", "2"); // java.lang.UnsupportedOperationException

Use Collections.unmodifiableSet()/Collections.unmodifiableList()/Collections.unmodifiableMap()

Set<String> set = new HashSet<>();
set.add("a");
set = Collections.unmodifiableSet(set);
set.add("b"); // java.lang.UnsupportedOperationException

List<String> list = new ArrayList<>();
list.add("a");
list = Collections.unmodifiableList(list);
list.add("b"); // java.lang.UnsupportedOperationException

Map<String, String> map = new HashMap<>();
map.put("a", "1");
map = Collections.unmodifiableMap(map);
map.put("b", "2"); // java.lang.UnsupportedOperationException

Conclusion

  • If programming rule is followed in coding, using <? extends T> in compile time is enough. E.g, no class casting is used.
  • To guarantee the read only of collection, the ways in run time should be considered. The perfect way to make collection read only is considering compile time and run time both.

Post Directory