Recherche…


Introduction

Les objets immuables sont des instances dont l'état ne change pas après son initialisation. Par exemple, String est une classe immuable et, une fois instanciée, sa valeur ne change jamais.

Remarques

Quelques classes immuables en Java:

  1. java.lang.String
  2. Les classes d'encapsulation pour les types primitifs: java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float
  3. La plupart des classes d'énumération sont immuables, mais cela dépend en fait du cas concret.
  4. java.math.BigInteger et java.math.BigDecimal (au moins les objets de ces classes eux-mêmes)
  5. java.io.Fichier. Notez que cela représente un objet externe à la machine virtuelle (un fichier sur le système local), qui peut exister ou non, et comporte certaines méthodes modifiant et interrogeant l'état de cet objet externe. Mais l'objet File lui-même reste immuable.

Règles pour définir des classes immuables

Les règles suivantes définissent une stratégie simple pour créer des objets immuables.

  1. Ne fournissez pas de méthodes "setter" - méthodes qui modifient les champs ou les objets auxquels les champs font référence.
  2. Rendez tous les champs définitifs et privés.
  3. Ne permettez pas aux sous-classes de remplacer les méthodes. La manière la plus simple de le faire est de déclarer la classe comme finale. Une approche plus sophistiquée consiste à rendre le constructeur privé et à construire des instances dans les méthodes d'usine.
  4. Si les champs d'instance contiennent des références à des objets mutables, ne permettez pas que ces objets soient modifiés:
  5. Ne fournissez pas de méthodes modifiant les objets mutables.
  6. Ne partagez pas les références aux objets mutables. Ne stockez jamais de références à des objets externes, mutables, transmis au constructeur; Si nécessaire, créez des copies et stockez les références aux copies. De même, créez des copies de vos objets internes mutables si nécessaire pour éviter de renvoyer les originaux dans vos méthodes.

Exemple sans références mutables

public final class Color {
    final private int red;
    final private int green;
    final private int blue;

    private void check(int red, int green, int blue) {
        if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public Color(int red, int green, int blue) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
    }

    public Color invert() {
        return new Color(255 - red, 255 - green, 255 - blue);
    }
}

Exemple avec des références mutables

Dans ce cas, la classe Point est mutable et certains utilisateurs peuvent modifier l'état de l'objet de cette classe.

class Point {
    private int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

//...

public final class ImmutableCircle {
    private final Point center;
    private final double radius;

    public ImmutableCircle(Point center, double radius) {
        // we create new object here because it shouldn't be changed
        this.center = new Point(center.getX(), center.getY());
        this.radius = radius;
    }

Quel est l'avantage de l'immuabilité?

L'avantage de l'immuabilité vient avec la concurrence. Il est difficile de maintenir une exactitude dans les objets mutables, car plusieurs threads pourraient essayer de changer l'état du même objet, ce qui conduit à ce que certains threads voient un état différent du même objet, en fonction du timing des lectures et des écritures. objet.

En ayant un objet immuable, on peut s'assurer que tous les threads qui regardent l'objet verront le même état, car l'état d'un objet immuable ne changera pas.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow