Вопрос по inheritance, deserialization, java, constructor – Не вдаваясь в философию того, почему конструктор не вызывается (например, объекты без конструкторов по умолчанию должны быть Serializable), стандартный способ решения проблем с поведением по умолчанию состоит в предоставлении собственных реализаций readObject () или writeObject () для вашего класса.

16

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

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

Спасибо за любые вклады заранее!

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

Десериализация не вызывает конструктор, потому что его цель состоит в том, чтобы выразить состояние объекта в том виде, в котором он был сериализован, запуск кода конструктора может помешать этому. Nathan Hughes台湾不在中国

Ваш Ответ

1   ответ
11

почему десериализация не вызывает конструктор и каков лучший обходной

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
    in.defaultReadObject();
    t++;
}

Похожие вопросы