Frage

Lassen Sie uns sagen, dass ich eine Instanz der Klasse B zu erstellen, die eine statische Variable x hat, mit einem Wert von 3 in der Klasse B Erklärung zugeordnet. In der Methode main (), das tue ich dies:

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

Nach diesem b wird serialisiert und dann de-serialisiert. Dann wird die folgende Zeile auftritt:

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

Was ist der Wert? 7 oder 3?

Ich weiß, statische Variablen serialisiert werden jedoch nicht, da es nur eine Kopie des statischen Elements für die ganze Klasse ist, und der Wert wird auf 7 gesetzt, sollte es nach dem de-Serialisierung eine Instanz erhalten?

War es hilfreich?

Lösung

Hier ist, was passiert:

  1. Statische Initialisierer setzt den Wert auf 3.
  2. Instanzkonstruktors setzt den Wert auf 7.
  3. Serialisierung ist keine Kenntnis von den statischen Variablen und es wird ignoriert.
  4. De-Serialisierung ist nicht bewusst statischen Variablen und es wird ignoriert.
  5. Der Wert ist immer noch 7 (von der Änderung, die im Konstruktor aufgetreten ist), wenn das Programm der ganze Zeit in Betrieb war, oder wenn das Programm Herunterfahren ist und neu gestartet wird, wird der statische Initialisierer gesetzt hat es bis 3 und Deserialisierung tat nicht ändern sie es.

Wenn Sie die Logik wollen Sie beschreiben, müssen Sie eine andere statische Variable hinzuzufügen, die die Anzahl der Instanzen zählt erstellt und überschreiben die writeObject und readObject Methoden mit Ihrem eigenen Logik.

Andere Tipps

Wenn Sie es in der gleichen Instanz der JVM deserialisieren, Ihre zweite Snippet 7. zurückkehren Dies wird, da der Wert von bx bis 7 festgelegt ist, hat da nicht geändert eine Instanz von B wurde serialisiert und deserialisiert.

Wenn Sie das Objekt serialisiert, Herunterfahren der JVM, eine neue JVM bringen, und dann Deserialisieren das Objekt (ohne b.x irgendwo anders als die statische Initialisierung gesetzt wird), wird der Wert von b.x 3 sein.

Verwenden Sie die folgenden Code zu serialisieren und deserialisieren und Objekt zu / von einem In-Memory-Strom:

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
    }
}

Nachdem diese Klasse zu schaffen, ist es mit einem JUnit runner laufen und sehen, ob der Test bestanden! Wenn Sie möchten, können Sie das Ergebnis in eine Datei in einem Testfall schreiben. Dann in einem anderen Testfall, lesen Sie das Ergebnis aus einer Datei!

Da statische Initialisierer genau einmal ausgeführt, der Wert 7.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top