logo

Як створити незмінний клас у Java?

У 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:

Java
import 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 або інші записи.