Вы должны, как правило, не выставлять внутренние структуры классов снаружи. Это особенно важно для вторичных.
Поэтому я предлагаю сделать копию с new ArrayList(x)
в вашем конструкторе.
Кроме того, вы можете использовать Collections.unmodifiableList()
для предотвращения изменений внутри вашего класса.
Я предлагаю сочетание обоих, которое будет выглядеть следующим образом:
import java.util.Collections;
...
public Container(List<String> strs){
this.strs = Collections.unmodifiableList(new ArrayList<>(strs));
}
Ваш контейнер будет помнить членов списка в момент вызова конструктора. Если список изменен в другом месте, это не повлияет на ваш imutable.
Даже код в контейнере не сможет изменить список - вместо этого вместо этого будет выбрано значение UnsupportedOperationException
.
полный, рабочий пример кода:
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
}
выводит:
a
b
(не выводит BUH!
)
Это не хорошо, чтобы полагаться на комментарии, чтобы направлять выбор программиста, потому что мы не всегда читать комментарии. Чаще всего мы полагаемся на пример кода и интуицию, чтобы решить, что можно сделать с объектом. –
«Выполнение копирования внутри конструктора не является желательным». Ну, но если вы этого не сделаете, вы не можете претендовать на неизменность. – Thilo
Лично я сделал бы копию в конструкторе. Это дает мне список, который я могу гарантировать, не будет добавлять, изменять порядок или терять элементы. Но если это должна быть глубокая копия или нет (т. Е. Если сами элементы должны быть неизменными) зависит от случая. – Thilo