Java: Почему десериализация не вызывает конструктор и как лучше всего обходиться?

В спецификации сериализации Java для Java 1.5 сказано:

Для сериализуемых объектов конструктор no-arg для первого несериализуемый супертип запущен. Для сериализуемых классов поля инициализируются значением по умолчанию, соответствующим его типу. Затем поля каждого класса восстанавливаются путем вызова специфичного для класса 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 выключен по одному.

Интересно, почему десериализация не вызывает конструктор ? Поскольку кажется, что, хотя это немного повысит скорость, это может вызвать потенциальные проблемы. Компилятор можно легко спроектировать для создания «статического конструктора», который обновляет только статические переменные, которые будут обновлены, и не полагается на внешнюю информацию при загрузке класса.

Кроме того, мне интересно, как лучше всего избежать это? Решение, которое я могу придумать, - это упаковать десериализацию с операцией над статической переменной.

Заранее спасибо за любые данные!

16
задан zw324 22 August 2011 в 18:14
поделиться