Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V6076. Recurrent serialization will use…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Дополнительная информация
Оглавление

V6076. Recurrent serialization will use cached object state from first serialization.

3 декабря 2019 г.

Анализатор обнаружил ситуацию, когда объект однажды уже записанный в поток, спустя какое-то время записывается в него снова с измененным состоянием. Из-за нюансов 'java.io.ObjectOuputStream' это приведет к тому, что измененное состояние сериализуемого объекта будет проигнорировано в пользу исходного.

Класс 'java.io.ObjectOuputStream', который используется для сериализации, кэширует записываемые объекты. Это означает, что один и тот же объект не будет сериализоваться дважды. Один раз класс сериализует объект, а во второй раз просто запишет в поток ссылку на тот же самый первый объект. В этом и кроется подводный камень. Если мы сериализуем объект, изменим его, а после снова сериализуем, то 'java.io.ObjectOuputStream' об изменениях объекта ничего не узнает, поэтому сочтет объект тем же самым, который был сериализован ранее.

Рассмотрим некорректный синтетический пример, в котором будет проигнорировано изменение состояния объекта при сериализации:

ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj); // сохраняет объект с состоянием = 100
obj.state = 200;
out.writeObject(obj); // сохраняет объект с состоянием = 100 (а ожидалось 200)
out.close();

Чтобы избежать подобного поведения, есть два способа.

Самым простым и надежным решением является создание нового экземпляра этого объекта с необходимым состоянием. Рассмотрим пример:

ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj);
obj = new SerializedObject();
obj.state = 200;
out.writeObject(obj);
out.close();

Следующий способ менее тривиален. Он заключается в использовании метода 'reset' класса 'java.io.ObjectOuputStream'. Использовать данный способ рекомендуется только тогда, когда вы хорошо понимаете, что делаете и зачем, так как 'reset' обнулит информацию обо всех объектах, ранее записанных в поток. Рассмотрим пример:

ObjectOutputStream out = new ObjectOutputStream(....);
SerializedObject obj = new SerializedObject();
obj.state = 100;
out.writeObject(obj);
out.reset();
obj.state = 200;
out.writeObject(obj);
out.close();
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять