Что такое неизменный объект?
Неизменяемый объект - это объект, который не изменит состояние после создания его экземпляра.
Как создать объектimmutable?
В общем случае неизменяемый объект можно создать, определив класс, для которого не выставлен ни один из его членов, и нет сеттеров.
Следующий класссоздаст неизменный объект:
class ImmutableInt {
private final int value;
public ImmutableInt(int i) {
value = i;
}
public int getValue() {
return value;
}
}
Как видно из приведенного выше примера, значение ImmutableInt
может быть установлено только при создании экземпляра объекта и при наличии только геттера (getValue
) состояние объекта не может быть изменено после создания экземпляра.
Однако необходимо позаботиться о том, чтобы все объекты, на которые ссылается объект, также были неизменяемыми, иначе можно было бы изменить состояние объекта.объект.
Например, разрешение получения ссылки на массив или ArrayList
через геттер позволит изменить внутреннее состояние путем изменения массива или коллекции:
class NotQuiteImmutableList<T> {
private final List<T> list;
public NotQuiteImmutableList(List<T> list) {
// creates a new ArrayList and keeps a reference to it.
this.list = new ArrayList(list);
}
public List<T> getList() {
return list;
}
}
Проблемас помощью приведенного выше кода можно получить ArrayList
через getList
и манипулировать им, что приведет к изменению состояния самого объекта, следовательно, не является неизменным.
// notQuiteImmutableList contains "a", "b", "c"
List<String> notQuiteImmutableList= new NotQuiteImmutableList(Arrays.asList("a", "b", "c"));
// now the list contains "a", "b", "c", "d" -- this list is mutable.
notQuiteImmutableList.getList().add("d");
В одну сторонуЧтобы обойти эту проблему, нужно вернуть копию массива или коллекции при вызове из получателя:
public List<T> getList() {
// return a copy of the list so the internal state cannot be altered
return new ArrayList(list);
}
В чем преимущество неизменности?
Преимущество неизменности приходит с параллелизмом.Трудно поддерживать корректность в изменчивых объектах, так как несколько потоков могут пытаться изменить состояние одного и того же объекта, что приводит к тому, что некоторые потоки видят другое состояние одного и того же объекта в зависимости от времени чтения и записи в упомянутый объект.object.
Имея неизменный объект, можно гарантировать, что все потоки, которые смотрят на объект, будут видеть одно и то же состояние, поскольку состояние неизменяемого объекта не изменится.