Kako ustvariti nespremenljiv razred v Javi?

V Javi nespremenljivost pomeni, da ko je predmet ustvarjen, njegovega notranjega stanja ni več mogoče spremeniti. Nespremenljivi razredi v Javi zagotavljajo številne prednosti, kot je varnost niti, enostavno odpravljanje napak in vse. V Javi vse ovojni razredi (kot Integer Boolean Byte Short) in razred String je nespremenljiv. Ustvarimo lahko tudi lasten nespremenljiv razred.

V tem članku se bomo naučili:

  • Kaj pomeni nespremenljivost
  • Zakaj je koristno
  • Kako ustvariti lasten nespremenljiv razred
  • Zakaj je globoko kopiranje pomembno
  • Kakšne so omejitve vrste zapisov Java

Kaj je nespremenljivi razred?

Nespremenljiv razred je razred, katerega objektov ni mogoče spremeniti, ko so ustvarjeni. Če naredimo kakršno koli spremembo, bo rezultat nov objekt. Ta metoda se uporablja v sočasnih aplikacijah.

Pravila za ustvarjanje nespremenljivega razreda

  • Razred mora biti deklariran kot dokončno tako da podrejenih razredov ni mogoče ustvariti.
  • Podatkovne člane v razredu je treba deklarirati zasebno tako da neposreden dostop ni dovoljen.
  • Podatkovne člane v razredu je treba deklarirati kot dokončno tako da po ustvarjanju predmeta ne moremo spremeniti njihove vrednosti.
  • Parametrizirani konstruktor bi moral inicializirati vsa polja, ki izvajajo a globoka kopija tako da podatkovnih članov ni mogoče spreminjati z referenco objekta.
  • Globinsko kopiranje objektov je treba izvesti v metodah pridobivanja, da se vrne kopija namesto vrnitve dejanskega sklica na objekt.

Opomba : Nastavljalcev ne bi smelo biti ali preprosteje rečeno ne bi smelo biti možnosti za spreminjanje vrednosti spremenljivke primerka.


Primer: implementacija nespremenljivega razreda

Študent.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  ;      }   }   

V tem primeru smo ustvarili končni razred z imenom študent. Ima tri končne podatkovne člane, parametrizirani konstruktor in metode pridobivanja. Upoštevajte, da tukaj ni nastavitvene metode. Upoštevajte tudi, da nam ni treba izvajati globokega kopiranja ali kloniranja podatkovnih članov tipov ovoja, saj so že nespremenljivi.

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  ());         }   }   

Tudi po spreminjanju izvirnega ali vrnjenega zemljevida ostane notranje stanje predmeta študenta nespremenjeno. To potrjuje koncept nespremenljivosti.

Izhod:

 GFG   
101
{1=first 2=second}
{1=first 2=second}
{1=first 2=second}


Omejitev zapisa Java s spremenljivimi polji

Predstavljena Java 14 zapis . To je jasen in jedrnat način za definiranje nespremenljivih podobnih razredov:

zapis Student(Ime niza int regNo Map metapodatki) {}


Toda to ponuja le plitvo nespremenljivost. Če se zemljevid spremeni od zunaj, se spremeni notranje stanje zapisa:

Zemljevid zemljevid = nov HashMap <>();

map.put('1' 'prvi');


Študent s = nov študent ('ABC' 101 zemljevid);


// Spremeni notranje stanje — NI varno

map.put('2' 'drugi');

s.metadata().put('3' 'tretji');

Opomba : Uporabite zapis le, če so vsa polja nespremenljive vrste, kot je String int ali drugi zapisi.