У Java незмінність означає, що після створення об’єкта його внутрішній стан не можна змінити. Незмінні класи в Java надають багато переваг, наприклад безпеку потоків, просте налагодження тощо. На Java все класи-обгортки (наприклад, Integer Boolean Byte Short), а клас String є незмінним. Ми також можемо створити свій власний незмінний клас.
У цій статті ми дізнаємося:
- Що означає незмінність
- Чому це корисно
- Як створити наш власний незмінний клас
- Чому глибоке копіювання важливо
- Які обмеження мають типи записів Java
Що таке незмінний клас?
Незмінний клас — це клас, створені об’єкти якого неможливо змінити. Якщо ми робимо будь-які зміни, це призводить до нового об’єкта. Цей метод використовується в паралельних програмах.
приклад підрядка java
Правила створення незмінного класу
- Клас повинен бути оголошений як остаточний так що дочірні класи не можуть бути створені.
- Члени даних у класі повинні бути оголошені приватний щоб прямий доступ був заборонений.
- Члени даних у класі мають бути оголошені як остаточний щоб ми не могли змінити їх значення після створення об’єкта.
- Параметризований конструктор повинен ініціалізувати всі поля, що виконують a глибока копія щоб члени даних не могли бути змінені за допомогою посилання на об’єкт.
- Глибоке копіювання об’єктів має виконуватися в методах отримання, щоб повертати копію, а не повертати фактичне посилання на об’єкт.
Примітка : Не повинно бути сеттерів або, простіше кажучи, не повинно бути можливості змінити значення змінної екземпляра.
Приклад: реалізація незмінного класу
Student.java
Java// Java Program to Create An Immutable Class import java.util.HashMap; import java.util.Map; // declare the class as final final class Student { // make fields private and final private final String name; private final int regNo; private final Map<String String> metadata; // initialize all fields via constructor public Student(String name int regNo Map<String String> metadata) { this.name = name; this.regNo = regNo; // deep copy of mutable object (Map) Map<String String> tempMap = new HashMap<>(); for (Map.Entry<String String> entry : metadata.entrySet()) { tempMap.put(entry.getKey() entry.getValue()); } this.metadata = tempMap; } // only provide getters (no setters) public String getName() { return name; } public int getRegNo() { return regNo; } // return deep copy to avoid exposing internal state public Map<String String> getMetadata() { Map<String String> tempMap = new HashMap<>(); for (Map.Entry<String String> entry : this.metadata.entrySet()) { tempMap.put(entry.getKey() entry.getValue()); } return tempMap; } }
У цьому прикладі ми створили остаточний клас під назвою студент. Він має три кінцевих члени даних: параметризований конструктор і методи отримання. Зверніть увагу, що тут немає методу встановлення. Також зауважте, що нам не потрібно виконувати глибоке копіювання або клонування членів даних типів оболонки, оскільки вони вже незмінні.
Geeks.java:
Javaimport java.util.HashMap; import java.util.Map; public class Geeks { public static void main(String[] args) { // create a map and adding data Map<String String> map = new HashMap<>(); map.put('1' 'first'); map.put('2' 'second'); // create an immutable Student object Student s = new Student('GFG' 101 map); // accessing data System.out.println(s.getName()); System.out.println(s.getRegNo()); System.out.println(s.getMetadata()); // try to modify the original map map.put('3' 'third'); System.out.println(s.getMetadata()); // try to modify the map returned by getMetadata() s.getMetadata().put('4' 'fourth'); System.out.println(s.getMetadata()); } }
Навіть після модифікації оригінальної або повернутої карти внутрішній стан об’єкта Student залишається незмінним. Це підтверджує концепцію незмінності.
Вихід:
GFG
101
{1=first 2=second}
{1=first 2=second}
{1=first 2=second}
Обмеження запису Java зі змінними полями
Представлено Java 14 запис . Це чіткий і стислий спосіб визначення незмінних подібних класів:
java довжина масиву
запис Student(String name int regNo Map
метадані) {}
Але це лише пропонує неглибоку незмінність. Якщо карту змінено ззовні, внутрішній стан запису змінюється:
Карта
map = нова HashMap<>(); map.put('1' 'перший');
Student s = new Student('ABC' 101 map);
екземпляр у java// Змінює внутрішній стан — НЕбезпечно
map.put('2' 'другий');
s.metadata().put('3' 'третій');
Примітка : використовуйте запис, лише якщо всі поля є незмінними типами, наприклад String int або інші записи.