web-dev-qa-db-fra.com

Manipulation finale des variables en Java

Quelqu'un pourrait-il me dire quelle est la signification de la ligne suivante dans le contexte de Java:

la variable finale peut encore être manipulé sauf si c'est immuable

Autant que je sache, en déclarant une variable comme étant finale, vous ne pouvez plus la changer, alors que signifie-t-elle avec Word immuable en haut de la ligne?

45
Dusk

Cela signifie que si votre variable finale est un type de référence (c'est-à-dire pas une primitive comme int), c'est uniquement la référence qui ne peut pas être modifiée. Il n'est pas possible de faire référence à un objet différent, mais les champs de l'objet auquel il fait référence peuvent toujours être modifiés, si la classe le permet. Par exemple:

final StringBuffer s = new StringBuffer();

Le contenu du StringBuffer peut toujours être modifié arbitrairement:

s.append("something");

Mais vous ne pouvez pas dire:

s = null;

ou

s = anotherBuffer;

D'autre part:

final String s = "";

Les chaînes sont immuables - aucune méthode ne vous permettrait simplement de modifier une chaîne (sauf si vous utilisez Reflection - et allez en enfer).

98
Michael Borgwardt

Si vous avez une référence finale à un objet Java, vous pouvez toujours le manipuler, mais vous ne pouvez pas changer sa référence. Par exemple, ce code est parfaitement légal:

import javax.swing.JLabel;

class Test1 {
    private final static JLabel l = new JLabel("Old text");
    public static void main(String[] args) {
        System.err.println(l.getText());
        l.setText("New Text");
        System.err.println(l.getText());
    }
}

Mais vous ne pouvez pas dire:

l = new JLabel("Newest Text");

Après la première affectation à l. Notez que vous pouvez le faire cependant:

import javax.swing.JLabel;

class Test1 {
    public static void main(String[] args) {
        final JLabel l;
        String s = getArbitaryString(); // Assume this method returns a string
        l = new JLabel(s);
        System.err.println(l.getText());
    }
}

Cela peut être fait car lorsque l est déclaré, il n'est pas affecté à quelque chose qui n'est même pas null. Vous êtes donc autorisé à lui attribuer quelque chose une seule fois.

Même chose pour les primitives. Vous pouvez lui attribuer une valeur comme ceci: 

class Test1 {
    public static void main(String[] args) {
        final int i;
        i = 2;
    }
}

Mais maintenant, vous ne pouvez plus le manipuler car la seule chose que vous pouvez faire pour les types primitifs est de leur attribuer des valeurs.

16
Savvas Dalkitsis

Vous ne pouvez pas changer l'objet ou la valeur auquel une variable finale fait référence. Vous ne pouvez affecter une variable finale qu’une seule fois.

Cela n'a aucun effet sur la possibilité de modifier l'état de l'objet. L'objet lui-même peut toujours être manipulé à moins d'être codé de manière à interdire cette manipulation. Un objet immuable est un objet dont l'état ne peut pas changer.

4
Fred

Comme d'autres l'ont déjà dit, cela signifie que vous pouvez manipuler l'objet sur lequel la variable pointe, mais vous ne pouvez pas modifier la référence (c'est-à-dire affecter un autre objet à la variable).

Les objets modifiables par conception, tels que List, peuvent être modifiés (vous pouvez leur ajouter des éléments), tandis que si vous avez un objet immuable tel que String ou Integer, vous ne pourrez pas le String prend en charge le retour d'une nouvelle instance et ne modifie pas l'objet réel).

3
pgb

Vous pouvez manipuler des variables finales mutables, par exemple. de type StringBuffer mais vous ne pouvez pas manipuler les variables finales de types immuables .

Dans le cas de variables modifiables, le nouvel objet n'est pas créé chaque fois que sa valeur est modifiée. Mais dans le cas de types immuables, chaque fois que vous modifiez une valeur, un nouvel objet est créé. Vous ne pouvez donc pas le modifier lorsque vous le définissez.

0
deepakraut

Vous pouvez appeler n'importe quelle méthode dessus même si la méthode peut changer l'état de l'objet pointé par la référence. Par exemple

final MyClass myClass = new MyClass();
myClass.setVar(something);

Cela convient car myClass ne change pas, c’est-à-dire que vous ne faites pas myClass = myClass1;.

0
fastcodejava

Oui, la variable finale peut être modifiée.

    final StringBuffer s = new StringBuffer();
    // won't work
    s = new StringBuffer();
    //this works
    s.append("hai");

Vous ne pouvez pas changer la référence mais les champs de l'objet peuvent être modifiés. pour plus de détails

0
vaisakh ps

Celui qui me tue toujours?

Si vous voulez que les variables finales soient aussi sûres que vous le pensiez, vous avez besoin de beaucoup de code supplémentaire pour renvoyer une copie d'un String []. 

0
Dean J