You should in general not expose internal structures of classes to the outside. This is espacially important for imutables.
Therefore I suggest to make a copy with new ArrayList(x)
in your constructor.
In addition you can use Collections.unmodifiableList()
to prevent modifications from inside your class.
I suggest the combination of both, which will look like this:
import java.util.Collections;
...
public Container(List<String> strs){
this.strs = Collections.unmodifiableList(new ArrayList<>(strs));
}
Your container will remember the members of the list at the time of the call of the constructor. If the list is changed somewhere else, it will not have any effect on your imutable.
Even the code within the container will not be able to modify the list - the list would throw an UnsupportedOperationException
instead.
The complete, working example code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class X {
public static void main(String[] args) {
// create a list
List<String> myList = new ArrayList<>();
myList.add("a");
myList.add("b");
// hand it over to the container
Container container = new Container(myList);
// modify it afterwards
myList.add("BUH!");
// check contents of container
for (String item : container.strs) {
System.out.println(item);
}
}
}
class Container{
final List<String> strs;
/**
* Contructs {@code Container} by a given {@code List}
* The content of the list referenced should not be modified
* after the constructor invokation.
*/
public Container(List<String> strs){
this.strs = Collections.unmodifiableList(new ArrayList<>(strs));
}
//Other staff
}
it outputs:
a
b
(does not output BUH!
)