Как можно сделать класс Java неизменным, какова потребность в неизменности и есть ли какое-то преимущество в использовании этого?
Неизменяемый класс?
Ответ 1
Что такое неизменяемый объект?
Неизменяемый объект - это тот, который не изменит состояние после его создания.
Как сделать объект неизменным?
В общем случае неизменяемый объект может быть создан путем определения класса, который не имеет ни одного из его членов, и не имеет каких-либо сеттеров.
Следующий класс создаст неизменяемый объект:
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);
}
В чем преимущество неизменности?
Преимущество неизменности приходит с concurrency. Трудно поддерживать правильность в изменяемых объектах, поскольку несколько потоков могут пытаться изменить состояние одного и того же объекта, приводя к тому, что некоторые потоки видят другое состояние одного и того же объекта, в зависимости от времени чтения и записи в упомянутый объект.
Имея неизменяемый объект, можно гарантировать, что все потоки, которые смотрят на объект, будут видеть одно и то же состояние, так как состояние неизменяемого объекта не изменится.
Ответ 2
В дополнение к уже предоставленным ответам я бы рекомендовал прочитать о неизменности в Effective Java, 2nd Ed., так как есть некоторые детали, которые легко пропустить (например, защитные копии). Кроме того, эффективная Java 2nd Ed. является обязательным для каждого разработчика Java.
Ответ 3
Вы делаете класс неизменным следующим образом:
public final class Immutable
{
private final String name;
public Immutable(String name)
{
this.name = name;
}
public String getName() { return this.name; }
// No setter;
}
Неизменяемые классы полезны, потому что они потокобезопасны. Они также выражают что-то глубокое в вашем дизайне: "Не могу изменить это". Когда это применимо, это именно то, что вам нужно.
Ответ 4
Неизменяемые классы не могут переопределять значения после его создания. Конструктор присваивает значения своим частным переменным. Пока объект не станет пустым, значения не могут быть изменены из-за недоступности методов setter.
чтобы быть неизменным, должно удовлетворять следующему,
- Al переменные должны быть private.
- Нет мутаторов методов (сеттеров).
- Избегайте переопределения методов, делая класс final (Сильная неизменность) или методы final (Непрерывность недели).
- Клон глубоко, если он содержит не примитивные или изменяемые классы.
/**
* Strong immutability - by making class final
*/
public final class TestImmutablity {
// make the variables private
private String Name;
//assign value when the object created
public TestImmutablity(String name) {
this.Name = name;
}
//provide getters to access values
public String getName() {
return this.Name;
}
}
Advanteges: Неизменяемые объекты содержат свои инициализированные значения до тех пор, пока они не умрут.
Ответ 5
Q1) Что такое неизменяемый класс и объект?
Ans) Необязательный класс - это класс, который когда-то был создан, его содержимое не может быть изменено. Неизменяемыми объектами являются объекты, состояние которых не может быть изменено после его создания. например Класс строк
Q2) Как создать неизменяемый класс?
Ans) Чтобы создать неизменяемый класс, выполните следующие шаги:
-
Создайте последний класс.
-
Задайте значения свойств, используя только конструктор.
-
Сделать свойства класса final и private
-
Не предоставляйте никаких настроек для этих свойств.
-
Если поля экземпляра включают ссылки на изменяемые объекты, не разрешить изменение этих объектов:
-
Не предоставляйте методы, изменяющие изменяемые объекты.
-
Не используйте ссылки на изменяемые объекты. Никогда не храните ссылки к внешним, изменяемым объектам, переданным конструктору; если необходимо, создавать копии и хранить ссылки на копии. Аналогичным образом создайте копии ваших внутренних изменяемых объектов, когда это необходимо, чтобы избежать возвращая оригиналы в ваших методах.
-
Ответ 6
Неизменяемость может быть достигнута главным образом двумя способами:
- с использованием атрибутов
final
экземпляра, чтобы избежать переназначения - с помощью интерфейса класса, который просто не позволяет выполнять какую-либо операцию, которая может изменить то, что находится внутри вашего класса (только getters и сеттеры
Преимущества неизменяемости - это предположения, которые вы можете сделать на этом объекте:
- вы получаете правило отсутствия побочных эффектов (которое действительно популярно на языках функционального программирования) и позволяет вам проще использовать объекты в параллельной среде, поскольку вы знаете, что они не могут быть изменены атомарным или неатомным способом когда они используются многими потоками.
- реализация языков может обрабатывать эти объекты по-другому, помещая их в зоны памяти, которые используются для статических данных, что позволяет быстрее и безопаснее использовать эти объекты (это то, что происходит внутри JVM для строк)
Ответ 7
-
Что такое неизменяемый?
Короче говоря, класс Immutable - это класс, чьи экземпляры не могут быть изменены. Информация, содержащаяся в каждом неизменяемом объекте, предоставляется при ее создании и замораживается на протяжении всего срока ее службы. Когда объект Immutable был создан, он читается только навсегда, как ископаемое.
-
Как сделать неизменяемый
- Сделать все поля частными и окончательными.
- Не предоставляйте какие-либо методы, которые изменяют состояние объектов.
- Убедитесь, что класс не может быть расширен.
- Обеспечить эксклюзивный доступ к любым изменяемым полям
<сильные > Преимущества
- Неизменяемые объекты являются потокобезопасными, поэтому у вас не будет никаких проблемы синхронизации.
- Неизменяемые объекты являются хорошими клавишами карты и элементами набора, поскольку эти обычно не изменяются после создания.
- Неизбежность упрощает запись, использование и использование кода (инвариант класса устанавливается один раз, а затем не изменяется)
- Неизбежность облегчает распараллеливание вашей программы, так как там не конфликты между объектами.
- Внутреннее состояние вашей программы будет согласованным, даже если вы имеют исключения.
- Ссылки на неизменяемые объекты можно кэшировать, поскольку они не собираются для изменения.
Как хорошая практика программирования в Java, следует попытаться использовать неизменяемые объекты, насколько это возможно. Неизменность может иметь стоимость исполнения, поскольку, когда объект не может быть мутирован, нам нужно его скопировать, если мы хотим его написать. Когда вы заботитесь о производительности (например, программировании игры), может потребоваться использование изменяемого объекта. Даже тогда часто бывает лучше попытаться ограничить изменчивость объектов.
-
Недостатки
Так как неизменяемый объект нельзя использовать повторно, они просто используются и бросаются. Строка является ярким примером, который может создать много мусора и может потенциально замедлить приложение из-за большой сборки мусора.
Ответ 8
Неизменяемый класс - это те, чьи объекты не могут быть изменены после создания.
Необязательные классы полезны для
- Цель кэширования
-
Параллельная среда (ThreadSafe)
-
Жесткий для наследования
- Значение не может быть изменено в любой среде
Пример
Класс строк
Пример кода
public final class Student {
private final String name;
private final String rollNumber;
public Student(String name, String rollNumber) {
this.name = name;
this.rollNumber = rollNumber;
}
public String getName() {
return this.name;
}
public String getRollNumber() {
return this.rollNumber;
}
}
Ответ 9
Другим способом создания неизменяемого объекта является библиотека Immutables.org:
Предполагая, что необходимые зависимости были добавлены, создайте абстрактный класс с абстрактными методами доступа. Вы можете сделать то же самое аннотирование с помощью интерфейсов или даже аннотаций (@interface):
package info.sample;
import java.util.List;
import java.util.Set;
import org.immutables.value.Value;
@Value.Immutable
public abstract class FoobarValue {
public abstract int foo();
public abstract String bar();
public abstract List<Integer> buz();
public abstract Set<Long> crux();
}
Теперь можно сгенерировать, а затем использовать сгенерированный неизменяемый реализация:
package info.sample;
import java.util.List;
public class FoobarValueMain {
public static void main(String... args) {
FoobarValue value = ImmutableFoobarValue.builder()
.foo(2)
.bar("Bar")
.addBuz(1, 3, 4)
.build(); // FoobarValue{foo=2, bar=Bar, buz=[1, 3, 4], crux={}}
int foo = value.foo(); // 2
List<Integer> buz = value.buz(); // ImmutableList.of(1, 3, 4)
}
}
Ответ 10
В: Что такое неизменяемый класс?
Объект неизменен, если его состояние не может измениться после построения, неизменяемые объекты не могут каким-либо образом изменить другие объекты для изменения своего состояния, поля объектов инициализируются только один раз внутри конструктора и никогда не будут меняться снова.
В: Как создать неизменяемый класс?
Чтобы создать неизменяемый класс, вы должны выполнить следующие шаги:
- Сделайте свой класс окончательным, чтобы другие классы не могли его расширять.
- Сделайте все свои поля окончательными, чтобы они инициализировались только один раз внутри конструктора и никогда не изменялся впоследствии.
- Не используйте методы setter.
- При экспонировании методов, которые изменяют состояние класса, вы должны всегда возвращайте новый экземпляр класса.
- Если класс содержит изменяемый объект:
Внутри конструктора обязательно используйте копию клона прошедшего аргумент и никогда не устанавливайте свое изменяемое поле в реальный экземпляр через конструктора, это значит, чтобы клиенты, которые передать объект после его модификации.
Обязательно всегда возвращайте копию клона поля и никогда не возвращайте экземпляр реального объекта.
Q: Преимущества неизменяемого класса?
потокобезопасна
Ответ 11
Как неродный английский говорящий, мне не нравится обычная интерпретация "неизменяемого класса", поскольку "построенные объекты класса неизменяемы"; скорее, я сам склоняюсь к тому, чтобы интерпретировать это как "сам объект класса неизменен".
Тем не менее, "неизменный класс" является своего рода непреложным объектом. Разница заключается в том, чтобы ответить на вопрос о том, какая польза. По моему знанию/интерпретации, неизменяемый класс не позволяет своим объектам изменять поведение во время выполнения.