Kuinka luoda muuttumaton luokka Javassa?

Javassa muuttumattomuus tarkoittaa, että kun objekti on luotu, sen sisäistä tilaa ei voi muuttaa. Javan muuttumattomat luokat tarjoavat monia etuja, kuten lankojen turvallisuuden, helppo virheenkorjaus ja kaikki. Javalla kaikki käärekurssit (kuten Integer Boolean Byte Short) ja String-luokka on muuttumaton. Voimme myös luoda oman muuttumattoman luokkamme.

Tässä artikkelissa opimme:

  • Mitä muuttumattomuus tarkoittaa
  • Miksi se on hyödyllistä
  • Kuinka luoda oma muuttumaton luokkamme
  • Miksi syväkopiointi on tärkeää
  • Mitkä ovat Java-tietuetyyppien rajoitukset

Mikä on muuttumaton luokka?

Muuttumaton luokka on luokka, jonka objekteja ei voi muuttaa luomisen jälkeen. Jos teemme muutoksia, tuloksena on uusi objekti. Tätä menetelmää käytetään samanaikaisissa sovelluksissa.

Muuttumattoman luokan luomisen säännöt

  • Luokka on ilmoitettava muodossa lopullinen jotta lapsiluokkia ei voida luoda.
  • Luokan datajäsenet on ilmoitettava yksityinen joten suora pääsy ei ole sallittu.
  • Luokan datajäsenet on ilmoitettava muodossa lopullinen jotta emme voi muuttaa niiden arvoa objektin luomisen jälkeen.
  • Parametrisoidun konstruktorin tulee alustaa kaikki kentät, jotka suorittavat a syvä kopio jotta datajäseniä ei voida muokata objektiviittauksella.
  • Objektien syväkopiointi tulisi suorittaa getter-menetelmissä kopion palauttamiseksi todellisen objektiviittauksen palauttamisen sijaan.

Huom : Ei pitäisi olla asettajia tai yksinkertaisemmin sanottuna ei pitäisi olla mahdollisuutta muuttaa ilmentymämuuttujan arvoa.


Esimerkki: Muuttumaton luokan toteutus

Opiskelija.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  ;      }   }   

Tässä esimerkissä olemme luoneet lopullisen luokan nimeltä Opiskelija. Siinä on kolme lopullista datajäsentä, parametroidut konstruktori- ja getterimenetelmät. Huomaa, että tässä ei ole asetusmenetelmää. Huomaa myös, että meidän ei tarvitse suorittaa syväkopiointia tai kloonausta kääretyyppien datajäsenistä, koska ne ovat jo muuttumattomia.

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

Jopa alkuperäisen tai palautetun kartan muuttamisen jälkeen opiskelijaobjektin sisäinen tila pysyy muuttumattomana. Tämä vahvistaa muuttumattomuuden käsitteen.

Lähtö:

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


Java-tietueen rajoitus muuttuvien kenttien kanssa

Java 14 esitelty tallentaa . Tämä on selkeä ja ytimekäs tapa määritellä muuttumattomat kaltaiset luokat:

tietue Opiskelija(merkkijonon nimi int regNo Kartta metatiedot) {}


Mutta tämä tarjoaa vain pinnallista muuttumattomuutta. Jos karttaa muutetaan ulkoisesti, tietueen sisäinen tila muuttuu:

Kartta kartta = uusi HashMap <>();

map.put('1' 'ensimmäinen');


Opiskelija s = uusi Opiskelija('ABC' 101 kartta);


// Muuttaa sisäistä tilaa — EI turvallista

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

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

Huom : Käytä tietuetta vain, jos kaikki kentät ovat muuttumattomia tyyppejä, kuten String int tai muita tietueita.