Oggetti immutabili in Java

1. Panoramica

In questo tutorial impareremo cosa rende un oggetto immutabile, come ottenere l'immutabilità in Java e quali vantaggi ne derivano.

2. Cos'è un oggetto immutabile?

Un oggetto immutabile è un oggetto il cui stato interno rimane costante dopo che è stato interamente creato .

Ciò significa che l'API pubblica di un oggetto immutabile ci garantisce che si comporterà allo stesso modo durante tutta la sua vita.

Se diamo uno sguardo alla classe String , possiamo vedere che anche quando la sua API sembra fornirci un comportamento mutabile con il suo metodo di sostituzione , la String originale non cambia:

String name = "baeldung"; String newName = name.replace("dung", "----"); assertEquals("baeldung", name); assertEquals("bael----", newName);

L'API fornisce metodi di sola lettura, non dovrebbe mai includere metodi che modificano lo stato interno dell'oggetto.

3. L' ultima parola chiave in Java

Prima di provare a ottenere l'immutabilità in Java, dovremmo parlare della parola chiave finale .

In Java, le variabili sono modificabili per impostazione predefinita, il che significa che possiamo cambiare il valore che contengono .

Utilizzando la parola chiave final quando si dichiara una variabile, il compilatore Java non ci consente di modificare il valore di quella variabile. Invece, segnalerà un errore in fase di compilazione:

final String name = "baeldung"; name = "bael...";

Nota che final ci proibisce solo di modificare il riferimento che la variabile contiene, non ci protegge dal cambiare lo stato interno dell'oggetto a cui si riferisce utilizzando la sua API pubblica:

final List strings = new ArrayList(); assertEquals(0, strings.size()); strings.add("baeldung"); assertEquals(0, strings.size());

Il secondo assertEquals fallirà perché l'aggiunta di un elemento all'elenco ne cambia la dimensione, quindi non è un oggetto immutabile.

4. Immutabilità in Java

Ora che sappiamo come evitare modifiche al contenuto di una variabile, possiamo usarlo per costruire l'API di oggetti immutabili.

La creazione dell'API di un oggetto immutabile richiede di garantire che il suo stato interno non cambierà indipendentemente da come utilizziamo la sua API.

Un passo avanti nella giusta direzione è usare final quando si dichiarano i suoi attributi:

class Money { private final double amount; private final Currency currency; // ... }

Nota che Java ci garantisce che il valore di amount non cambierà, questo è il caso di tutte le variabili di tipo primitivo.

Tuttavia, nel nostro esempio ci viene solo garantito che la valuta non cambierà, quindi dobbiamo fare affidamento sull'API Currency per proteggerci dalle modifiche .

Il più delle volte, abbiamo bisogno degli attributi di un oggetto per contenere valori personalizzati e il luogo in cui inizializzare lo stato interno di un oggetto immutabile è il suo costruttore:

class Money { // ... public Money(double amount, Currency currency) { this.amount = amount; this.currency = currency; } public Currency getCurrency() { return currency; } public double getAmount() { return amount; } }

Come abbiamo detto prima, per soddisfare i requisiti di un'API immutabile, la nostra classe Money ha solo metodi di sola lettura.

Utilizzando l'API di riflessione, possiamo rompere l'immutabilità e modificare gli oggetti immutabili. Tuttavia, la riflessione viola l'API pubblica dell'oggetto immutabile e, in genere, dovremmo evitare di farlo.

5. Benefici

Poiché lo stato interno di un oggetto immutabile rimane costante nel tempo, possiamo condividerlo in modo sicuro tra più thread .

Possiamo anche usarlo liberamente e nessuno degli oggetti che fanno riferimento noterà alcuna differenza, possiamo dire che gli oggetti immutabili sono privi di effetti collaterali .

6. Conclusione

Gli oggetti immutabili non cambiano il loro stato interno nel tempo, sono thread-safe e privi di effetti collaterali. A causa di queste proprietà, gli oggetti immutabili sono anche particolarmente utili quando si ha a che fare con ambienti multi-thread.

Puoi trovare gli esempi utilizzati in questo articolo su GitHub.