Zielony Smok - logo witryny

Co to znaczy 'immutable’?

Immutable – znaczy dosłownie 'nie mutujący’, 'niezmienny’.

Jako immutable określane są na przykład instancje klasy String w języku Java.

Ale co to właściwie oznacza?

Przeanalizujmy to na przykładzie klasy ImmutableDragon.

Klasa ImmutableDragon.java
package immutable;

import java.util.*;

public final class ImmutableDragon {
    private final String imie;
    private final int pesel;
    private final int[] peselePotomstwa;

    public ImmutableDragon(String imie, int pesel, int[] peselePotomstwa) {
        this.imie = imie;
        this.pesel = pesel;
        this.peselePotomstwa = peselePotomstwa;
    }

    public String getImie() {
        return imie;
    }

    public int getPesel() {
        return pesel;
    }

    public int[] getPeselePotomstwa() {
        return Arrays.copyOf(peselePotomstwa, peselePotomstwa.length);
    }
}

Cechy klasy, której instancje są 'immutable’

A oto cechy tej klasy:

  • Wartości wszystkich pól (imie, pesel, peselePotomstwa) – są ustawione w konstruktorze
  • Ponieważ pola mają atrybut final – nie mogą być później zmienione
  • Brak jest metod ustawiających (setters), są jedynie pobierające (getters)
  • Metody getters zwracają klony obiektów, a nie same obiekty. W przypadku getPesel() nie jest to potrzebne, bo zwracany jest typ prosty, a nie obiektowy. Nie jest to też potrzebne przy zwracaniu stringu – ponieważ jak wiadomo obiekty klasy String same są 'immutable’.
  • Klasa ma atrybut final co oznacza, że nie można utworzyć klas potomnych dziedziczących po tej klasie – chodzi o zapobieżenie możliwości napisania metod setters ustawiających wartości. Jeśli wszystkie pola są final – to klasa niekoniecznie musi być final, bo i tak pola nie dadzą się zmienić. Dlatego np. klasa BigInteger nie jest oznaczona jako final.

W instancji tak napisanej klasy, nie można zmienić żadnego z pól. Cokolwiek z tym obiektem zrobimy – zawsze otrzymujemy nowy obiekt.