Java Immutable Classes: Definitive Guide
First of all, let’s define what is an immutable object in Java.
It’s one of the most popular interview questions.
An immutable object is an object that constructed once and can’t be changed in future.
How to create an immutable class in Java?
- Make fields private and final .
- Make class final to prohibit inheritance.
- Don’t create setters or any other methods, that can modify fields.
- If field refers to a mutable object you should not allow to modify it as well – getter or any other method should return a deep copy of that object.
package com.explainjava; public final class Car < private final String color; private final Engine engine; public Car(String color, Engine engine) < this.color = color; this.engine = new Engine(engine.getName()); >public String getColor() < return color; >public Engine getEngine() < return new Engine(engine.getName()); >>
Note that I create a new Engine() object in the getter and in the constructor to protect it.
Another way to go is to implement Cloneable interface and use clone() method.
What are advantages of immutable classes?
- Thread-safe: it’s easier to synchronize and parallelize your program.
- It’s a good choice for a key in HashMap or element of the HashSet because hash code cannot be changed.
- Better security: for example, network connections, database connection URL, usernames/passwords are strings, developers don’t want to let them change easily, that’s why Java string is immutable.
Programmers usually worry about the cost of creating a new object instead of updating object fields in place.
The documentation says that impact of object creation is often overestimated.
Keep reading and I’ll provide more immutable class examples in Java, explain what is immutable collections and give you a tip how to build immutable objects faster.
Immutable in Java
It’s one more popular interview question: “could you list a Java immutable classes?”.
I already mentioned string immutable class as an example.
- Wrapper classes of primitive types: Integer, Long, Boolean, Character etc.
- Locale
- UUID
- LocalDate, LocalTime and LocalDateTime
- Optional
It’s just a small list of classes that provides immutability in Java.
How To Create Immutable Collections in Java?
First of all, what is an immutable collection?
It’s collection where you can’t add or delete elements.
Take a look at java.util.Collections class.
It provides a list of methods to create immutable collections:
- public static ListunmodifiableList (Listlist)
- public static MapunmodifiableMap (Map m)
- public static NavigableMapunmodifiableNavigableMap (NavigableMapm)
- public static NavigableSetunmodifiableNavigableSet (NavigableSets)
- public static SetunmodifiableSet (Set s)
- public static SortedMapunmodifiableSortedMap (SortedMapm)
- public static SortedSetunmodifiableSortedSet (SortedSets)
It’s really simple to use – provide a collection (List, Set, Map) as an input parameter and get an immutable collection as an output.
Collections class provides methods that return empty collections, it’s immutable as well:
- public static Enumeration emptyEnumeration ()
- public static IteratoremptyIterator ()
- public static ListemptyList ()
- public static ListIteratoremptyListIterator ()
- public static MapemptyMap ()
- public static NavigableMapemptyNavigableMap ()
- public static NavigableSetemptyNavigableSet ()
- public static SetemptySet ()
- public static SortedMapemptySortedMap ()
- public static SortedSetemptySortedSet ()
There 3 methods for single element collection in java.util.Collections :
- public static Setsingleton (T o)
- public static ListsingletonList (T o)
- public static MapsingletonMap (K key, V value)
and it’s immutable as well.
When you’re converting an array to list Arrays.asList(arr) you’re getting immutable list.
Since Java 9 collection interfaces provide methods of() that build immutable collections.
This API looks similar to google guava collections API.
Guava provides an amount self-built immutable collections like ImmutableList , ImmutableSet , ImmutableMap etc.
You can follow the link above and read about all of them.
Lombok Immutable Class Syntax Sugar
Lombok project is a library that tries to beautify Java code, make it cleaner and shorter.
It can replace this 20 lines of code:
package com.explainjava; public final class Car < private final String color; private final int year; public Car(String color, int year) < this.color = color; this.year = year; >public String getColor() < return color; >public int getYear() < return year; >>
With just 10 lines that include @Value Lombok annotation on the class level:
package com.explainjava; import lombok.Value; @Value public class Car
@Value annotation automatically adds:
- final to the class.
- private and final to fields.
- getters.
- toString() , equals() and hashCode() methods.
- constructor for all arguments.
Note that Lombok doesn’t know how to clone mutable objects, that’s why you should write this code manually.
Any question about immutability in Java? Ask me.
Java immutable types of
Вопрос глуппый но задам. Сборщик мусора не сходит сума при работе с immutable? Наример нам приходится в программе таскать ‘с собой’ масивы строк и паралельно в них менять значения. Это жесть какая нагрузка на железо.
public static void main(String[] args)
Вывод: I love Java I love Java Честно говоря, не понимаю, что удивительного в этом коде? Код же выполняется сверху вниз. А тут четверть статьи этому посвятили) Я так понимаю, что если я в конце в коде напишу: System.out.println(str1);, то вывод будет: I love Java I love Python Или я что-то не так понял?
Ведьмаку заплатите – чеканной монетой, чеканной монетой, во-о-оу Ведьмаку заплатите, зачтется все это вам
Всё что я должен понять из этой статьи: final для класса — класс нельзя наследовать, final для метода — метод нельзя переопределять, final для переменной — нельзя изменять первое присвоенное значение (сразу присваивать не обязательно), имя пишется капсом, слова через нижний пробел. Объекты всех классов обёрток, StackTrace, а также классы, используемые для создания больших чисел BigInteger и BigDecimal неизменяемые. Таким образом, при создании или изменении строки, каждый раз создаётся новый объект. Кратко о String Pool: Строки, указанные в коде литералом, попадают в String Pool (другими словами «Кэш строк»). String Pool создан, чтобы не создавать каждый раз однотипные объекты. Рассмотрим создание двух строковых переменных, которые указаны в коде литералом (без new String).
String test = "literal"; String test2 = "literal";
При создании первой переменной, будет создан объект строка и занесён в String Pool. При создании второй переменной, будет произведён поиск в String Pool. Если такая же строка будет найдена, ссылка на неё будет занесена во вторую переменную. В итоге будет две различных переменных, ссылающихся на один объект.
Мало примеров и в целом, недосказано. Под конец вскользь упомянут String Pool, а что это не объясняется. Статья озаглавлена какFinal & Co, а по факту пару примеров по строкам, ну, такое. Это называется собирались пироги печь, а по факту лепёшки лепим. В любом случае, конечно, спасибо за труд. Но, гораздо лучше про строки написано здесь: Строки в Java (class java.lang.String). Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder (более детальная статья на Хабре).
Получается мы не можем создать поле какого нибудь класса не константой public static final String name = «Амиго»; обязательно только так? => public static final String CHARACTER_NAME = «Амиго»; или можно написать и так и так?
«В прошлых лекциях мы видели простой пример наследования: у нас был родительский класс Animal, и два класса-потомка — Cat и Dog» ?! А была лекция о наследовании?! Может быть я где-то пропустил, поделитесь ссылкой, пожалуйста 🙂