1 votes

Quelle est la valeur des variables statiques après la désérialisation d'un objet ?

Supposons que je crée une instance de la classe B, qui possède une variable statique x, à laquelle la déclaration de la classe B attribue la valeur 3. Dans la méthode main(), je fais ceci :

B b = new B();
b.x = 7; //allowed to use an instance to set the static member value

Ensuite, b est sérialisé puis désérialisé. Ensuite, la ligne suivante apparaît :

System.out.println ("static: " + b.x);

Quelle est la valeur ? 7 ou 3 ?

Je sais que les variables statiques ne sont pas sérialisées, cependant, puisqu'il n'y a qu'une seule copie du membre statique pour toute la classe, et que la valeur est fixée à 7, devrait-elle être conservée après la dé-sérialisation d'une instance ?

6voto

Jared Points 7800

Si vous le désérialisez dans la même instance de la JVM, votre deuxième extrait renverra 7. C'est parce que la valeur de b.x est fixée à 7. Cela n'a pas changé parce que une instance de B a été sérialisé et désérialisé.

Si vous sérialisez l'objet, que vous arrêtez la JVM, que vous lancez une nouvelle JVM, puis que vous désérialisez l'objet (sans définir b.x ailleurs que dans l'initialisation statique), la valeur de b.x sera 3.

6voto

Benoit Points 39210

Voici ce qui se passe :

  1. L'initialisateur statique fixe la valeur à 3.
  2. Le constructeur de l'instance fixe la valeur à 7.
  3. La sérialisation ne connaît pas la variable statique et l'ignore.
  4. La désérialisation ne connaît pas les variables statiques et les ignore.
  5. La valeur est toujours 7 (suite au changement survenu dans le constructeur) si le programme est en cours d'exécution depuis le début, ou si le programme a été arrêté et redémarré, l'initialisateur statique l'aura fixée à 3 et la désérialisation ne l'a pas changée.

Si vous voulez la logique que vous décrivez, vous devez ajouter une autre variable statique qui compte le nombre d'instances créées et remplacer la fonction writeObject y readObject avec votre logique personnalisée.

1voto

les2 Points 3854

Utilisez le code suivant pour sérialiser et désérialiser un objet vers/depuis un flux en mémoire :

package com.example.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; 
import junit.framework.TestCase;

public class SerializationTest extends TestCase {
    public void testStaticValueAfterSerialization() {
       B b = new B();
       b.x = 7; //allowed to use an instance to set the static member value

       B deserializedB = copyObject(b);
       assertEquals("b.x should be 7 after serialization", 7, deserializedB.x);
    }

    private <T extends Serializable> T copyObject(final T source) {
        if (source == null)
                throw new IllegalArgumentException("source is null");
        final T copy;
        try {
            copy = serializationClone(source);
            } catch (Exception e) {
                // (optional) die gloriously!
            throw new AssertionError("Error copying: " + source, e);
        }    
            return copy;
    }

    private <T extends Serializable> T serializationClone(final T source)
        throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    ObjectOutputStream outputStream = new ObjectOutputStream(byteStream);

            // 1. serialize the object to the in-memory output stream
        outputStream.writeObject(source);

        ObjectInputStream inputStream = new ObjectInputStream(
                new ByteArrayInputStream(byteStream.toByteArray()));

        // 2. deserialize the object from the in-memory input stream
        @SuppressWarnings("unchecked")
            final T copy = (T) inputStream.readObject();

        return copy; // NOPMD : v. supra
    }
}

Après avoir créé cette classe, exécutez-la avec un programme d'exécution JUnit et voyez si le test réussit ! Si vous le souhaitez, vous pouvez écrire le résultat dans un fichier dans un cas de test. Puis, dans un autre scénario de test, lire le résultat à partir d'un fichier !

0voto

Aaron Digulla Points 143830

Étant donné que les initialisateurs statiques ne s'exécutent qu'une seule fois, la valeur est la suivante 7 .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X