logo

Как да създадете неизменен клас в Java?

В Java неизменността означава, че след като обектът е създаден, неговото вътрешно състояние не може да бъде променено. Неизменните класове в Java осигуряват много предимства като безопасност на нишки, лесно отстраняване на грешки и всичко останало. В Java всички обвиващи класове (като Integer Boolean Byte Short) и класът String е неизменен. Можем да създадем и наш собствен неизменен клас.

В тази статия ще научим:



  • Какво означава неизменност
  • Защо е полезно
  • Как да създадем наш собствен неизменен клас
  • Защо дълбокото копиране е важно
  • Какви са ограниченията, които имат типовете записи на Java

Какво е неизменен клас?

Неизменен клас е клас, чиито обекти не могат да бъдат променяни, след като бъдат създадени. Ако направим някаква модификация, това води до нов обект. Този метод се използва в едновременни приложения.

Правила за създаване на неизменен клас

  • Класът трябва да бъде деклариран като окончателен така че да не могат да се създават дъщерни класове.
  • Членовете на данните в класа трябва да бъдат декларирани частен така че директният достъп не е разрешен.
  • Членовете на данните в класа трябва да бъдат декларирани като окончателен така че да не можем да променим тяхната стойност след създаването на обекта.
  • Параметризираният конструктор трябва да инициализира всички полета, изпълняващи a дълбоко копие така че членовете на данните да не могат да бъдат модифицирани с препратка към обект.
  • Дълбокото копиране на обекти трябва да се извършва в методите за получаване, за да се върне копие, вместо да се върне действителната препратка към обекта.

Забележка : Не трябва да има сетери или казано по-просто, не трябва да има опция за промяна на стойността на променливата на екземпляра.




Пример: Реализация на неизменен клас

Студент.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 запис . Това е ясен и кратък начин за дефиниране на неизменни като класове:

алгоритъм на кабината

запис Student(Име на низ int regNo Картаметаданни) {}


Но това предлага само плитка неизменност. Ако картата се модифицира външно, вътрешното състояние на записа се променя:

Картакарта = нова HashMap<>();

map.put('1' 'първи');


Student s = нов ученик ('ABC' 101 карта);


// Променя вътрешното състояние — НЕ е безопасно

map.put('2' 'втори');

s.metadata().put('3' 'трети');

Забележка : Използвайте запис само ако всички полета са неизменни типове като String int или други записи.

как да промените низ на int