Uforanderlige objekter i Java

1. Oversikt

I denne opplæringen lærer vi hva som gjør et objekt uforanderlig, hvordan man oppnår uforanderlighet i Java, og hvilke fordeler som følger med å gjøre det.

2. Hva er et uforanderlig objekt?

Et uforanderlig objekt er et objekt hvis indre tilstand forblir konstant etter at den er helt opprettet.

Dette betyr at den offentlige APIen til et uforanderlig objekt garanterer oss at det vil oppføre seg på samme måte i løpet av hele levetiden.

Hvis vi tar en titt på klassen String, kan vi se at selv når API-en ser ut til å gi oss en foranderlig oppførsel med sin erstatte metoden, originalen String endres ikke:

String name = "baeldung"; Streng newName = name.replace ("møkk", "----"); assertEquals ("baeldung", navn); assertEquals ("bael ----", newName);

API-et gir oss skrivebeskyttede metoder, det skal aldri inkludere metoder som endrer objektets interne tilstand.

3. Den endelig Nøkkelord i Java

Før vi prøver å oppnå uforanderlighet i Java, bør vi snakke om endelig nøkkelord.

I Java, variabler er mutable som standard, noe som betyr at vi kan endre verdien de har.

Ved å bruke endelig nøkkelord når deklarerer en variabel, lar Java-kompilatoren oss ikke endre verdien på den variabelen. I stedet rapporterer det en kompileringsfeil:

endelig strengnavn = "baeldung"; navn = "bael ...";

Noter det endelig bare forbyr oss å endre referansen variabelen inneholder, den beskytter oss ikke mot å endre den interne tilstanden til objektet den refererer til ved å bruke sin offentlige API:

endelige listestrenger = ny ArrayList (); assertEquals (0, strings.size ()); strings.add ("baeldung"); assertEquals (0, strings.size ());

Den andre hevderEquals vil mislykkes fordi å legge til et element i listen endrer størrelsen, derfor er det ikke et uforanderlig objekt.

4. Uforanderlighet i Java

Nå som vi vet hvordan vi kan unngå endringer i innholdet i en variabel, kan vi bruke den til å bygge API for uforanderlige objekter.

Å bygge API for et uforanderlig objekt krever at vi garanterer at dets interne tilstand ikke vil endres uansett hvordan vi bruker APIen.

Et skritt fremover i riktig retning er å bruke endelig når deklarerer attributtene:

klassepenger {privat endelig dobbeltbeløp; privat sluttvaluta valuta; // ...}

Merk at Java garanterer at verdien av beløp vil ikke endre seg, det er tilfelle med alle primitive typevariabler.

Imidlertid er vi i vårt eksempel bare garantert at valuta vil ikke endre seg, så vi må stole på Valuta API for å beskytte seg mot endringer.

Mesteparten av tiden trenger vi attributtene til et objekt for å ha tilpassede verdier, og stedet for å initialisere den interne tilstanden til et uforanderlig objekt er dets konstruktør:

klasse Penger {// ... offentlige penger (dobbelt beløp, valuta) {this.amount = beløp; denne.valuta = valuta; } offentlig valuta getCurrency () {returvaluta; } offentlig dobbel getAmount () {returbeløp; }}

Som vi har sagt før, for å oppfylle kravene til en uforanderlig API, vår Penger klassen har bare skrivebeskyttede metoder.

Ved hjelp av refleksjon API, kan vi bryte uforanderlighet og endre uforanderlige objekter. Imidlertid bryter refleksjon det uforanderlige objektets offentlige API, og vanligvis bør vi unngå å gjøre dette.

5. Fordeler

Siden den indre tilstanden til et uforanderlig objekt forblir konstant i tid, vi kan dele det trygt mellom flere tråder.

Vi kan også bruke den fritt, og ingen av objektene som refererer til den vil merke noen forskjell, det kan vi si uforanderlige gjenstander er gratis.

6. Konklusjon

Uforanderlige objekter endrer ikke sin indre tilstand i tide, de er trådsikre og er ikke bivirkningsfrie. På grunn av disse egenskapene er uforanderlige objekter også spesielt nyttige når det gjelder miljøer med flere tråder.

Du kan finne eksemplene som brukes i denne artikkelen på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found