# Immutable Class
Immutable objects are instances whose state doesn’t change after it has been initialized. For example, String is an immutable class and once instantiated its value never changes.
# Example without mutable refs
# What is the advantage of immutability?
The advantage of immutability comes with concurrency. It is difficult to maintain correctness in mutable objects, as multiple threads could be trying to change the state of the same object, leading to some threads seeing a different state of the same object, depending on the timing of the reads and writes to the said object.
By having an immutable object, one can ensure that all threads that are looking at the object will be seeing the same state, as the state of an immutable object will not change.
# Rules to define immutable classes
The following rules define a simple strategy for creating immutable objects.
- Don’t provide "setter" methods — methods that modify fields or objects referred to by fields.
- Make all fields final and private.
- Don’t allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
- If the instance fields include references to mutable objects, don’t allow those objects to be changed:
- Don’t provide methods that modify the mutable objects.
- Don’t share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
# Example with mutable refs
In this case class Point is mutable and some user can modify state of object of this class.
How To Create an Immutable Class in Java
This article provides an overview of how to create an immutable class in Java programming.
An object is immutable when its state doesn’t change after it has been initialized. For example, String is an immutable class and, once instantiated, the value of a String object never changes. Learn more about why the String class is immutable in Java.
Because an immutable object can’t be updated, programs need to create a new object for every change of state. However, immutable objects also have the following benefits:
- An immutable class is good for caching purposes because you don’t have to worry about the value changes.
- An immutable class is inherently thread-safe, so you don’t have to worry about thread safety in multi-threaded environments.
Creating an Immutable Class in Java
To create an immutable class in Java, you need to follow these general principles:
- Declare the class as final so it can’t be extended.
- Make all of the fields private so that direct access is not allowed.
- Don’t provide setter methods for variables.
- Make all mutable fields final so that a field’s value can be assigned only once.
- Initialize all fields using a constructor method performing deep copy.
- Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.
The following class is an example that illustrates the basics of immutability. The FinalClassExample class defines the fields and provides the constructor method that uses deep copy to initialize the object. The code in the main method of the FinalClassExample.java file tests the immutability of the object.
Create a new file called FinalClassExample.java and copy in the following code:
Compile and run the program:
Note: You might get the following message when you compile the file: Note: FinalClassExample.java uses unchecked or unsafe operations because the getter method is using an unchecked cast from HashMap<String,String> to Object . You can ignore the compiler warning for the purposes of this example.
You get the following output:
The output shows that the HashMap values didn’t change because the constructor uses deep copy and the getter function returns a clone of the original object.
What happens when you don’t use deep copy and cloning
You can make changes to the FinalClassExample.java file to show what happens when you use shallow copy instead of deep copy and return the object insetad of a copy. The object is no longer immutable and can be changed. Make the following changes to the example file (or copy and paste from the code example):
- Delete the constructor method providing deep copy and add the constructor method providing shallow copy that is highlighted in the following example.
- In the getter function, delete return (HashMap<String, String>) testMap.clone(); and add return testMap; .
The example file should now look like this:
Compile and run the program:
You get the following output:
The output shows that the HashMap values got changed because the constructor method uses shallow copy there is a direct reference to the original object in the getter function.
Conclusion
You’ve learned some of the general principles to follow when you create immutable classes in Java, including the importance of deep copy. Continue your learning with more Java tutorials.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Как сделать класс неизменяемым java
Immutable class in java means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like Integer, Boolean, Byte, Short) and String class is immutable. We can create our own immutable class as well. Prior to going ahead do go through characteristics of immutability in order to have a good understanding while implementing the same. Following are the requirements:
- The class must be declared as final so that child classes can’t be created.
- Data members in the class must be declared private so that direct access is not allowed.
- Data members in the class must be declared as final so that we can’t change the value of it after object creation.
- A parameterized constructor should initialize all the fields performing a deep copy so that data members can’t be modified with an object reference.
- Deep Copy of objects should be performed in the getter methods to return a copy rather than returning the actual object reference)
Note: There should be no setters or in simpler terms, there should be no option to change the value of the instance variable.
Иммутабельность в Java
Привет, Хабр. В преддверии скорого старта курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)» подготовили для вас традиционный перевод материала.
Приглашаем также всех желающих поучаствовать в открытом демо-уроке «Конструкторы и блоки инициализации». На этом бесплатном вебинаре мы:
— Разберём конструктор на запчасти
— Определим финалистов (финальные переменные)
— Наведём порядок (инициализации)

Иммутабельный (неизменяемый, immutable) класс — это класс, который после инициализации не может изменить свое состояние. То есть если в коде есть ссылка на экземпляр иммутабельного класса, то любые изменения в нем приводят к созданию нового экземпляра.
Чтобы класс был иммутабельным, он должен соответствовать следующим требованиям:
Должен быть объявлен как final, чтобы от него нельзя было наследоваться. Иначе дочерние классы могут нарушить иммутабельность.
Все поля класса должны быть приватными в соответствии с принципами инкапсуляции.
Для корректного создания экземпляра в нем должны быть параметризованные конструкторы, через которые осуществляется первоначальная инициализация полей класса.
Для исключения возможности изменения состояния после инстанцирования, в классе не должно быть сеттеров.
Для полей-коллекций необходимо делать глубокие копии, чтобы гарантировать их неизменность.
Иммутабельность в действии
Начнем со следующего класса, который, на первый взгляд, выглядит иммутабельным:
Теперь посмотрим на него в действии.
Очевидно, что мы хотим запретить добавление элементов в коллекцию, поскольку это изменение состояния объекта, то есть отсутствие иммутабельности.
Здесь мы изменили метод getFieldMap , который теперь возвращает глубокую копию коллекции, ссылка на которую есть в AlmostMutableClass . Получается, что если мы получим Map , вызвав метод getFieldMap , и добавим к нему элемент, то на map из нашего класса это никак не повлияет. Изменится только map , которую мы получили.
Однако если у нас остается доступ к исходной map , которая была передана в качестве параметра конструктору, то все не так уж и хорошо. Мы можем изменить ее, тем самым изменив состояние объекта.
Мы забыли, что в конструкторе нужно сделать то же самое, что и в методе getFieldMap . В итоге конструктор должен выглядеть так:
Хотя использование иммутабельных объектов дает преимущества, но их использование не всегда оправдано. Обычно нам нужно как создавать объекты, так и модифицировать их для отражения изменений, происходящих в системе.
То есть нам нужно изменять данные, и нелогично создавать новые объекты при каждом изменении, так как это увеличивает используемую память, а мы хотим разрабатывать эффективные приложения и оптимально использовать ресурсы системы.
Иммутабельность строк в Java
Класс String , представляющий набор символов, вероятно, самый популярный класс в Java. Его назначение — упростить работу со строками, предоставляя различные методы для их обработки.
Например, в классе String есть методы для получения символов, выделения подстрок, поиска, замены и многие другие. Как и другие классы-обертки в Java (Integer, Boolean и т.д.), класс String является иммутабельным.
Иммутабельность строк дает следующие преимущества:
Для строк можно использовать специальную область памяти, называемую «пул строк». Благодаря которой две разные переменные типа String с одинаковым значением будут указывать на одну и ту же область памяти.
Строки отличный кандидат для ключей в коллекциях, поскольку они не могут быть изменены по ошибке.
Класс String кэширует хэш-код, что улучшает производительность хеш-коллекций, использующих String .
Чувствительные данные, такие как имена пользователей и пароли, нельзя изменить по ошибке во время выполнения, даже при передаче ссылок на них между разными методами.