Каково значение статических переменных после десериализации объекта? - PullRequest
1 голос
/ 18 декабря 2009

Допустим, я создаю экземпляр класса B, который имеет статическую переменную x, которой присвоено значение 3 в объявлении класса B. В методе main () я делаю это:

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

После этого b сериализуется, а затем десериализуется. Затем происходит следующая строка:

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

Какое значение? 7 или 3?

Я знаю, что статические переменные не сериализуются, так как для всего класса существует только одна копия статического члена и значение равно 7, должно ли оно сохраняться после десериализации экземпляра?

Ответы [ 4 ]

8 голосов
/ 18 декабря 2009

Вот что происходит:

  1. Статический инициализатор устанавливает значение 3.
  2. Конструктор экземпляра устанавливает значение 7.
  3. Сериализация не знает о статической переменной и игнорируется.
  4. Десериализация не знает о статической переменной и игнорируется.
  5. Значение по-прежнему равно 7 (из изменения, произошедшего в конструкторе), если программа работала все время, или если программа была закрыта и перезапущена, статический инициализатор установит ее на 3, а десериализация не измени это.

Если вам нужна логика, которую вы описываете, вам нужно добавить еще одну статическую переменную, которая будет подсчитывать количество созданных экземпляров и переопределить методы writeObject и readObject с помощью вашей пользовательской логики.

7 голосов
/ 18 декабря 2009

Если вы десериализовали его в том же экземпляре JVM, ваш второй фрагмент вернет 7. Это потому, что значение bx установлено в 7. Это не изменилось, потому что экземпляр B был сериализован и десериализован.

Если вы сериализуете объект, выключаете JVM, запускаете новую JVM, а затем десериализуете объект (без установки bx где-либо, кроме статической инициализации), значение bx будет3.

1 голос
/ 18 декабря 2009

Используйте следующий код для сериализации и десериализации и возражения в / из потока в памяти:

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

После создания этого класса запустите его с помощью бегуна JUnit и посмотрите, прошел ли тест! Если хотите, вы можете записать результат в файл в одном тестовом примере. Затем в другом тестовом примере прочитайте результат из файла!

0 голосов
/ 18 декабря 2009

Поскольку статические инициализаторы запускаются ровно один раз, значение равно 7.

...