Since the collections created via, e.g. List.of(…)
or List.copyOf(…)
do not reflect subsequent changes to the specified array or collection and are immutable in general, it’s not possible to perform modifications after construction and in absence of concurrent modifications, there can’t be any thread safety issues.
The remaining question is whether the construction of these collections itself is immune to unsafe publication. Generally, you should use the proper constructs for publishing objects to other threads and not rely on unsafe publication.
But to recall, Unmodifiable Lists say
- They are unmodifiable. Elements cannot be added, removed, or replaced. Calling any mutator method on the List will always cause
UnsupportedOperationException
to be thrown. However, if the contained elements are themselves mutable, this may cause the List's contents to appear to change.
…
and following the value-based link, we find:
Value-based Classes
Some classes, such as java.lang.Integer
and java.time.LocalDate
, are value-based. A value-based class has the following properties:
- the class declares only final instance fields (though these may contain references to mutable objects);
…
Final fields are important for immutable objects intended to be immune to unsafe publication. As JLS§17.5. final
Field Semantics specifies:
final
fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code.
But we still have to assume the intent “to implement thread-safe immutable objects” on the JDK developer’s side rather than, e.g. the intent to surprise developers by explicitly using final
fields and then deliberately spoiling the safety guarantees.
If in doubt, just use safe publication. It won’t hurt.
And even if you already said this, it’s important to emphasize that this does not apply to the contained elements if they are mutable.