Hvordan lage en uforanderlig klasse i Java

Hvordan lage en uforanderlig klasse i Java

I Java er det å lage uforanderlige klasser en viktig praksis for å oppnå datakonsistens og sikkerhet. Uforanderlige klasser er klasser der objektene ikke kan endres etter at de er opprettet. Dette betyr at en gang et objekt er opprettet, kan ikke dets tilstand endres.

Uforanderlige klasser har mange fordeler:

* Sikkerhet: Uforanderlige klasser er tryggere å bruke i flertrådete omgivelser fordi de ikke kan endres samtidig av flere tråder.
* Konsistens: Siden objektene ikke endres, er du sikker på at tilstanden til et uforanderlig objekt alltid er den samme.
* Caching: Uforanderlige objekter kan brukes som nøkler i hashtabeller og for andre caching-mekanismer.
* Rebruk: Uforanderlige objekter kan brukes på nytt i mange forskjellige sammenhenger uten bekymring for å endre deres tilstand.

Denne artikkelen vil gi deg en detaljert guide til hvordan du lager uforanderlige klasser i Java.

Hvilke regler må følges for å lage en uforanderlig klasse?

For å lage en uforanderlig klasse i Java, må du følge noen nøkkelregler:

1. Alle feltene bør være final: Deklarer alle feltene i klassen som final. Dette sikrer at feltene ikke kan endres etter at objektet er opprettet.
2. Ingen mutatormetoder: Unngå å lage metoder som endrer verdien av feltene. Du bør heller ikke tillate bruk av setter-metoder.
3. Returner nye objekter i mutator-liknende metoder: Hvis du trenger å endre tilstanden til et objekt, bør du i stedet returnere et nytt objekt med de ønskede endringene.
4. Lag en kopi av mutable objekter: Hvis du har mutable objekter som felter i din uforanderlige klasse, bør du lage en kopi av disse objektene når du oppretter en ny forekomst. Dette forhindrer at koden din utilsiktet endrer tilstanden til de originale objektene.

Eksempel: En uforanderlig Person-klasse

Her er et eksempel på en uforanderlig Person-klasse:

java
public final class Person {
private final String navn;
private final int alder;
private final String by;

public Person(String navn, int alder, String by) {
this.navn = navn;
this.alder = alder;
this.by = by;
}

public String getNavn() {
return navn;
}

public int getAlder() {
return alder;
}

public String getBy() {
return by;
}
}

I dette eksemplet er alle feltene deklarert som final. Klassen har også kun gettere for å hente verdiene til feltene, og ingen settmetoder som kan endre disse verdiene.

Eksempel på bruk av uforanderlig klasse

java
public class Main {
public static void main(String[] args) {
Person person1 = new Person("Ola", 30, "Oslo");
System.out.println("Navn: " + person1.getNavn());
System.out.println("Alder: " + person1.getAlder());
System.out.println("By: " + person1.getBy());

// Umulig å endre verdiene til feltene:
// person1.setNavn("Kari"); // Feil: Kan ikke endre 'final'-feltet
}
}

Hvordan håndtere mutable objekter i uforanderlige klasser?

Hva om du trenger å bruke mutable objekter i en uforanderlig klasse? La oss si at Person-klassen også skal inneholde en Adresse-klasse som er mutable. I dette tilfellet er det viktig å lage en kopi av Adresse-objektet når du oppretter en Person-forekomst.

java
public class Adresse {
private String gate;
private int husnummer;

public Adresse(String gate, int husnummer) {
this.gate = gate;
this.husnummer = husnummer;
}

// ... setter-metoder for gate og husnummer ...
}

public final class Person {
private final String navn;
private final int alder;
private final Adresse adresse;

public Person(String navn, int alder, Adresse adresse) {
this.navn = navn;
this.alder = alder;
this.adresse = new Adresse(adresse.getGate(), adresse.getHusnummer()); // Lag kopi
}

// ... gettere for navn, alder og adresse ...
}

I dette eksemplet oppretter Person-konstruktøren en ny Adresse-forekomst ved å bruke informasjonen fra den oppgitte adresse-objektet. Dette sikrer at Adresse-objektet som er lagret i Person-klassen er uavhengig av opprinnelig Adresse-objekt og kan ikke endres av ekstern kode.

Fordeler med uforanderlige klasser

Uforanderlige klasser har flere fordeler:

* Sikkerhet i flertrådete omgivelser: Siden de ikke kan endres, er det trygt for flere tråder å bruke uforanderlige objekter samtidig. Det er ingen sjanse for at én tråd kan endre et objekt mens en annen tråd bruker det.
* Enklere testing: Du trenger ikke å bekymre deg for at tilstanden til et objekt skal endres i løpet av en test, da det er alltid den samme.
* Bedre caching: Du kan lage en cache med uforanderlige objekter, da du er sikker på at de alltid vil være de samme og du ikke trenger å sjekke om de er endret.
* Forklarbarhet: Uforanderlige objekter er enklere å forstå, da deres tilstand er fast og ikke endres over tid.

Oppsummering

Ved å følge reglene for å lage uforanderlige klasser i Java, kan du sørge for at programvaren din er mer sikker, konsistent og enkel å vedlikeholde. Uforanderlige klasser er et viktig verktøy for å forbedre kvaliteten på kodebasen din.

Vanlige spørsmål om uforanderlige klasser

1. Hvordan håndterer jeg mutable objekter i uforanderlige klasser?

For å håndtere mutable objekter i uforanderlige klasser bør du lage en kopi av disse objektene når du oppretter en ny forekomst. Dette sikrer at de opprinnelige objektene ikke kan endres av ekstern kode. Du kan bruke konstruktøren til å lage en ny kopi av det mutable objektet når du oppretter en ny forekomst av den uforanderlige klassen.

2. Hvorfor bør jeg bruke uforanderlige klasser?

Uforanderlige klasser bidrar til å forbedre sikkerheten, konsistensen og forståeligheten av koden din. De er også nyttige for caching og multithreading.

3. Er det noen ulemper ved å bruke uforanderlige klasser?

Ulempen med å bruke uforanderlige klasser er at det kan være litt mer ressurskrevende å lage nye objekter hver gang du trenger å gjøre en endring. Men fordelene med uforanderlighet veier ofte opp for denne lille ulempen.

4. Hva er forskjellen mellom final og immutable?

final betyr at verdien til et felt ikke kan endres. Immutable betyr at objektet som helhet ikke kan endres etter at det er opprettet. Et uforanderlig objekt kan ha final-felter, men det kan også ha felter som ikke er final hvis disse feltene ikke endrer objektets tilstand.

5. Hvordan kan jeg lage uforanderlige samlinger i Java?

Java tilbyr immutable samlinger som Collections.unmodifiableList(), Collections.unmodifiableSet(), og Collections.unmodifiableMap(). Disse metodene returnerer en ny immutable samling basert på den opprinnelige samlingen.

6. Kan jeg bruke StringBuilder i en uforanderlig klasse?

Nei, StringBuilder er en mutable klasse og bør ikke brukes i uforanderlige klasser. Hvis du trenger å bruke en strengbuffer, kan du bruke String eller StringBuffer i stedet.

7. Hvordan kan jeg lage en uforanderlig klasse som inneholder en mutable klasse som felt?

Du kan lage en uforanderlig klasse som inneholder en mutable klasse som felt ved å lage en kopi av det mutable objektet når du oppretter en ny forekomst av den uforanderlige klassen. For eksempel, hvis du har en Person-klasse som inneholder en mutable Address-klasse, kan du lage en ny Address-forekomst i Person-konstruktøren ved å bruke verdiene fra den oppgitte Address-forekomsten.

8. Hvordan kan jeg bestemme om en klasse er uforanderlig eller ikke?

En klasse er uforanderlig hvis:

* Alle feltene er final.
* Det er ingen settmetoder som endrer tilstanden til objektet.
* Eventuelle mutable objekter som felter blir kopiert når objektet opprettes.

9. Er det mulig å lage en uforanderlig klasse som inneholder mutable data?

Ja, det er mulig å lage en uforanderlig klasse som inneholder mutable data. Men du må sikre at det mutable dataet ikke kan endres utenfra ved å lage en kopi av mutable data når du oppretter en ny forekomst av den uforanderlige klassen.

10. Hvilke biblioteker kan hjelpe meg å lage uforanderlige klasser i Java?

Det finnes biblioteker som kan hjelpe deg med å lage uforanderlige klasser i Java, for eksempel Immutables* og *Apache Commons Lang3. Disse bibliotekene tilbyr verktøy for å generere uforanderlige klasser og for å håndtere mutable objekter i uforanderlige klasser.

Tags: Java, Immutable, Programming, Object-Oriented Programming, Design Patterns, Software Development, Best Practices, Efficiency, Security, Multithreading, Caching, Collections, Immutable Collections, Immutables, Apache Commons Lang3

Links:

* Immutables library
* Apache Commons Lang3
* Java Documentation – Final