Я написал свой класс Container<T>
, который создает резервные копии своих T
элементов в нескольких коллекциях - первичный - List<T>
, другие - разные карты с данными, полученными из элементов, в основном для оптимизированного поиска.Deserialized object имеет значение null во всех полях
класса выглядит следующим образом:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private final Map<...> map1 = Maps.newHashMap();
private final Map<...> map2 = Maps.newHashMap();
}
Стандартный сериализации работает как шарм, но карты не нужно сериализовать. Я попытался установить карты в качестве transient
и использовать readObject()
таким образом:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private transient Map<...> map1;
private transient Map<...> map2;
public Container() {
initContainer();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initContainer();
}
private void initContainer() {
map1 = Maps.newHashMap();
map2 = Maps.newHashMap();
// prepare data in maps
for (T item: items) {
map1.put(...);
map2.put(...);
}
}
}
Простой тест с ObjectOutputStream.writeObject()
и ObjectInputStream.readObject()
снова работает. Но когда я интегрирую Container
в реальное приложение, где этот класс сериализуется и десериализуется как часть других сложных классов (фактически на странице Wicket), происходят странные вещи.
Я сделал некоторые отладки и вот мои выводы:
- сериализация
Container
с (п) элементами сделали OK - десериализация
Container
сделала OK - десериализации каждого
T
элемента называется только (n-1) раз (путем подсчета звонков на его методreadObject()
) - в
containerInit()
имеетList<T>
правильный (n) количество элементов, но один из них (Что один, для которого не называется десериализации) находится в очень странном состоянии - все поля имеютnull
значение - и мой код здесь бросает NPE
Вопросы:
- Какое состояние имеет этот странный объект после десериализации (он существует, но без
readObject()
вызов и с нулевым значением во всех полях)? - Возможно, десериализация этого странного объекта не завершена, но я прочитал, что чтение объектов из
ObjectInputStream
блокируется, поэтому все объекты в моем списке должны быть в правильном состоянии. Или я что-то забыл? - Есть ли какая-либо техника/инструмент/практика для ловли вещей вроде этого?
спасибо.
Пара вопросов: неупорядочен ли десериализованный объект один и тот же? Если да, то как его состояние отличается от других? Кроме того, всякий раз, когда десериализуются объекты, неплохо предположить, что они из враждебного источника и соответственно проверяют их состояние для таких вещей, как нули или что-то еще, что скомпрометирует ваше приложение. –
Этот объект не одинаковый в каждом случае, прежде чем сериализация ссылается на пару других объектов в приложении - это полностью здоровый объект, прежде чем сериализация вызывает метод 'writeObject()'. У меня есть еще один важный вывод: когда я не перехожу через 'items' в' Container.readObject() '(или' initContainer() 'на самом деле), все работает! Похоже, я не могу коснуться десериализованных данных right-now в 'readObject()', он должен быть отложен после завершения сериализации. Возможно, это зависит от существующих ссылок на объект до начала сериализации ... очень странно ... – mschayna