Java'da Değişmez Sınıf Nasıl Oluşturulur?

Java'da değişmezlik, bir nesne oluşturulduktan sonra dahili durumunun değiştirilemeyeceği anlamına gelir. Java'daki değişmez sınıflar, iş parçacığı güvenliği, kolay hata ayıklama ve benzeri birçok avantaj sağlar. Java'da tüm sarmalayıcı sınıfları (Integer Boolean Byte Short gibi) ve String sınıfı değişmezdir. Kendi değişmez sınıfımızı da oluşturabiliriz.

Bu yazıda şunları öğreneceğiz:

  • Değişmezlik ne anlama gelir?
  • Neden faydalıdır?
  • Kendi değişmez sınıfımızı nasıl oluşturabiliriz?
  • Derin kopyalama neden önemlidir?
  • Java kayıt türlerinin sahip olduğu sınırlamalar nelerdir?

Değişmez Sınıf Nedir?

Değişmez bir sınıf, nesneleri oluşturulduktan sonra değiştirilemeyen bir sınıftır. Herhangi bir değişiklik yaparsak, yeni bir nesneyle sonuçlanır. Bu yöntem eş zamanlı uygulamalarda kullanılır.

Değişmez Bir Sınıf Oluşturma Kuralları

  • Sınıf olarak bildirilmelidir son böylece alt sınıflar oluşturulamaz.
  • Sınıftaki veri üyeleri bildirilmelidir özel böylece doğrudan erişime izin verilmez.
  • Sınıftaki veri üyeleri şu şekilde bildirilmelidir: son böylece nesne oluşturulduktan sonra değerlerini değiştiremeyiz.
  • Parametreli bir kurucu, bir işlemi gerçekleştiren tüm alanları başlatmalıdır. derin kopya böylece veri üyeleri bir nesne referansıyla değiştirilemez.
  • Nesnelerin Derin Kopyası, gerçek nesne referansını döndürmek yerine bir kopya döndürmek için alıcı yöntemlerinde gerçekleştirilmelidir.

Not : Hiçbir ayarlayıcı bulunmamalı veya daha basit bir ifadeyle örnek değişkenin değerini değiştirme seçeneği olmamalıdır.


Örnek: Değişmez sınıf uygulaması

Öğrenci.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  ;      }   }   

Bu örnekte adında son bir sınıf oluşturduk. Öğrenci. Parametrelendirilmiş yapıcı ve alıcı yöntemleri olmak üzere üç son veri üyesine sahiptir. Lütfen burada ayarlayıcı bir yöntem olmadığını unutmayın. Ayrıca, sarmalayıcı türlerinin veri üyelerinin zaten değişmez olması nedeniyle derin kopyalama veya klonlama yapmamıza gerek olmadığını da unutmayın.

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

Orijinal veya döndürülen Harita değiştirildikten sonra bile Öğrenci nesnesinin dahili durumu değişmeden kalır. Bu değişmezlik kavramını doğrulamaktadır.

Çıkış:

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


Değişken Alanlarla Java kaydının sınırlandırılması

Java 14 tanıtıldı kayıt . Bu, değişmez benzer sınıfları tanımlamanın açık ve kısa bir yoludur:

kayıt Öğrenci(Dize adı int regNo Harita) meta veriler) {}


Ancak bu yalnızca yüzeysel değişmezlik sunar. Harita harici olarak değiştirilirse kaydın dahili durumu değişir:

Harita harita = yeni HashMap <>();

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


Öğrenci s = yeni Öğrenci('ABC' 101 haritası);


// Dahili durumu değiştirir — Güvenli DEĞİLDİR

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

s.metadata().put('3' 'üçüncü');

Not : Record'u yalnızca tüm alanların String int veya diğer kayıtlar gibi değişmez türler olması durumunda kullanın.