logo

Ako vytvoriť nemennú triedu v jazyku Java?

V Jave nemennosť znamená, že akonáhle je objekt vytvorený, jeho vnútorný stav sa nedá zmeniť. Nemenné triedy v Jave poskytujú mnoho výhod, ako je bezpečnosť vlákien, jednoduché ladenie a podobne. V Jave všetky obalové triedy (ako Integer Boolean Byte Short) a trieda String je nemenná. Môžeme si vytvoriť aj vlastnú nemennú triedu.

pole v jazyku Java

V tomto článku sa naučíme:



  • Čo znamená nemennosť
  • Prečo je to užitočné
  • Ako vytvoriť vlastnú nemennú triedu
  • Prečo je hlboké kopírovanie dôležité
  • Aké sú obmedzenia typov záznamov Java

Čo je to nemenná trieda?

Nemenná trieda je trieda, ktorej objekty sa po vytvorení nedajú zmeniť. Ak vykonáme akúkoľvek úpravu, výsledkom bude nový objekt. Táto metóda sa používa v súbežných aplikáciách.

Pravidlá pre vytvorenie nemennej triedy

  • Trieda musí byť deklarovaná ako konečná aby nebolo možné vytvárať detské triedy.
  • Dátové členy v triede musia byť deklarované súkromné takže priamy prístup nie je povolený.
  • Dátové členy v triede musia byť deklarované ako konečná aby sme po vytvorení objektu nemohli zmeniť ich hodnotu.
  • Parametrizovaný konštruktor by mal inicializovať všetky polia vykonávajúce a hlboká kópia aby údajové členy nebolo možné upravovať pomocou odkazu na objekt.
  • Hlboká kópia objektov by sa mala vykonávať v metódach getra, aby sa vrátila kópia, a nie vrátenie skutočného odkazu na objekt.

Poznámka : Nemali by existovať žiadne nastavovače alebo jednoduchšie povedané, nemala by existovať možnosť zmeniť hodnotu premennej inštancie.




Príklad: Implementácia nemennej triedy

Š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 tomto príklade sme vytvorili konečnú triedu s názvom Študent. Má tri konečné dátové členy, parametrizovaný konštruktor a metódy getra. Upozorňujeme, že tu neexistuje žiadna metóda nastavenia. Všimnite si tiež, že nemusíme vykonávať hlboké kopírovanie alebo klonovanie údajových členov typov wrapperov, pretože sú už nemenné.



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

Aj po úprave pôvodnej alebo vrátenej mapy zostáva vnútorný stav objektu Študent nezmenený. To potvrdzuje koncept nezmeniteľnosti.

výstup:

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


Obmedzenie záznamu Java s meniteľnými poliami

Predstavená Java 14 záznam . Toto je jasný a stručný spôsob, ako definovať nemenné podobné triedy:

record Student(String name int regNo Mapmetadáta) {}


To však ponúka len plytkú nemennosť. Ak je mapa upravená externe, vnútorný stav záznamu sa zmení:

Mapamapa = nová HashMap<>();

zapuzdrenie java

map.put('1' 'prvý');


Študent s = new Student('ABC' 101 map);


// Zmení interný stav — NIE JE bezpečné

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

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

Poznámka : Použite záznam len vtedy, ak sú všetky polia nemenného typu, ako napríklad String int alebo iné záznamy.