=== unmodifiableList is a VIEW: changes to the backing list show through ===
backing = [a, b, c]
view    = [a, b, c]
after backing.add("d"):
backing = [a, b, c, d]
view    = [a, b, c, d]  <- changed, with no code touching 'view' directly

=== List.copyOf is a SNAPSHOT: changes to the source do NOT show through ===
source = [x, y, z]
copy   = [x, y, z]
after source.add("w"):
source = [x, y, z, w]
copy   = [x, y, z]  <- unchanged, it was a real copy at the moment copyOf() ran

=== List.copyOf has a documented optimization: copying an already-immutable list is a no-op ===
List.copyOf(List.of(...)) returns the SAME instance: true
List.copyOf(new ArrayList<>(...)) returns a DIFFERENT instance: true

=== Map and Set follow the same pattern as List ===
unmodMapView after mutating backing map = {one=1, two=2}  (view: changed)
mapCopy after mutating the ORIGINAL map  = {one=1}  (copy: unchanged)
