2012-02-13 3 views
2

У меня есть сериализованный объект MyObject, который содержит целое число foo. Я устанавливаю значение 10 в целое число foo и сохраняю объект в файле с помощью writeObject().Предотвращение значений параметров сериализации Java по умолчанию

Я добавляю целочисленную панель для объекта MyObject. Я устанавливаю значение 15 в целочисленную строку, а затем загружаю старый сериализованный файл с помощью readObject().

Старый сериализуемый файл не содержит целых баров, поэтому целочисленная строка будет получать значение 0. Я хочу сохранить значение 15 в баре, если старый сериализуемый файл не содержит переменную строку.

Должен ли я переопределить readObject() или как я могу запретить readObject() устанавливать значения по умолчанию для неизвестных объектов?

Я хочу сделать это, потому что в конструкторе я устанавливаю свои собственные значения по умолчанию и хотел бы использовать собственные значения по умолчанию для управления версиями.

ответ

1

Сериализация не устанавливает значения по умолчанию, они переходят к схеме инициализации по умолчанию Java.

Если я могу подвести ваш вопрос. Вы хотите, чтобы сериализация объединила то, что в сериализованном потоке, со значениями в памяти. Это невозможно с сериализацией Java, поскольку она контролирует, какие объекты создавать. Вы можете прочитать в своем сериализованном объекте, а затем вручную написать код, чтобы объединить какие поля вы хотите объединить вместе. Если вы застряли на сериализации Java (я бы избегал этого, если бы я был вами), но, допустим, вы хотите продолжать использовать его.

public class MyObject { 

    public void merge(MyObject that) { 
     // given some other instance of an object merge this with that. 
     // write your code here, and you can figure out the rules for which values win. 
    } 
} 

ObjectInputStream stream = new ObjectInputStream(new FileInputStream(file)); 
MyObject that = stream.readObject(); 
someObject.merge(that); 

Виола вы контролируете, какие поля будут слиты из этого в someObject. Если вы хотите, чтобы библиотека сделала это слияние, вы проверите http://flexjson.sourceforge.net. Он использует сериализацию JSON и работает от Beans, а не POJO. Тем не менее, есть способ взять уже заполненный объект и перезаписать значения из потока JSON. Есть ограничения на это. Другим преимуществом этого является то, что вы действительно можете прочитать поток назад ПОСЛЕ того, как ваша структура объектов изменила то, что может быть реализована в Java-сериализации, но очень тяжело.

+0

Спасибо, это хороший ответ. Я рад, что не зациклился на сериализации. Что бы вы предложили вместо этого? Мне нужен способ хранения объекта в виде файла и хорошего контроля над ним. – Mikuz

+0

Если долговременное хранение - это ваша цель, я бы определенно сказал, используя что-то вроде flexjson. Вы всегда можете прочитать данные обратно, используя любую желаемую структуру объекта. Сериализация Java намного сложнее и граничит с невозможным, если у вас нет структуры объекта и пакета.Всякий раз, когда я пытался использовать сериализацию Java для долговременного хранения, я в конечном итоге копирую ее и заменяю. – chubbsondubs

+0

Найдено XStream очень полезно. – Mikuz

0

Используйте ключевое слово transient, чтобы исключить поля из сериализации/десериализации.

+0

Я хочу сериализовать и десериализовать бар. Я просто не хочу, чтобы значение десериализации по умолчанию было применено, если в десериализованном контенте не существует бар. – Mikuz

+0

@ user1207523, Затем просто реализуйте такую ​​логику в методе 'readObject' (или' readResolve() '). – mre

0

Добавил бы в ваш проект MyObject следующий метод?

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException 
{ 
    bar = 15; // Set a default value of 15 if it's not in the serialized output file 
    ois.defaultReadObject(); 
} 
+0

Не совсем, он будет переопределен в чтении. Хотя это работает для меня, так как bar не может быть равным нулю. ois.defaultReadObject(); если (бар == 0) бар = 15; Спасибо. Тем не менее я надеюсь, что мы сможем найти для этого лучший ответ. – Mikuz

+0

Интересно. Я либо полагаюсь на неопределенное поведение здесь (очень возможно), либо делаю что-то другое, чем вы. В моем тесте (с использованием сериализованного объектного файла перед добавлением строки в мой класс) чтение не переопределяет значение, и я получаю 15 в конце. Только если мой серийный объектный файл содержит панель в первую очередь, она переопределяет ее. Надеюсь, вы сможете найти лучший ответ. – spdaley

Смежные вопросы