Спецификация Java-сериализации для Java 1.5 сообщает:
Для сериализуемых объектов конструктор без аргументов для первого
несериализуемый супертип запущен. Для сериализуемых классов
поля инициализируются значением по умолчанию, соответствующим его типу.
Затем поля каждого класса восстанавливаются путем вызова конкретного класса
методы readObject или, если они не определены, путем вызова
метод defaultReadObject. Обратите внимание, что инициализаторы полей и
конструкторы не выполняются для сериализуемых классов во время
десериализации.
Однако это означает, что если мы поместим в класс статическую переменную (например, переменную-счетчик), она не будет обновляться, как обычно:
class Foo {
static int t;
public Foo() {
t++;
}
}
public class Bar extends Foo implements Serializable {
static int t;
public Bar() {
t++;
}
}
В этом случае, если десериализуется один экземпляр Bar
, то счетчик для Foo
является правильным, а счетчик для Bar
отключен на единицу.
Интересно, почему десериализация не вызывает конструктор? Поскольку кажется, что это немного прибавит в скорости, это может вызвать потенциальные проблемы. Компилятор может быть легко спроектирован для создания «статического конструктора», который обновляет только статические переменные, которые будут обновлены, и не полагается на внешнюю информацию при загрузке класса.
Кроме того, мне интересно, как лучше всего избежать этого? Решение, которое я могу придумать, заключается в упаковке десериализации операцией над статической переменной.
Спасибо за любые вклады заранее!