2011-12-22 4 views
1

Я сериализации объекта к сгустка в SQLiteOpenHelper так:Поддержание Serializable класса в Java/Android

final ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
final ObjectOutputStream out = new ObjectOutputStream(bos); 
out.writeObject(value); 
out.close(); 

Каждый класс определить свою собственную serialVersionUID, что никогда не изменится.

Как работает сериализация/десериализация? Помнит ли это имя поля и значение, связанное с ним? Если я продолжаю добавлять/удалять поле, существует ли вероятность изменения существующего поля?

Например, скажем, я сериализовать этот класс:

public class Foo implements Serializable { 
    private static final long serialVersionUID = 4068188167994381987L; 
    String x; 
    int y; 
} 

Where x is "A", and y is 1; 

Тогда я изменить класс, как так:

public class Foo implements Serializable { 
    private static final long serialVersionUID = 4068188167994381987L; 
    float f; 
    String x; 
} 

Если я продолжаю добавлять/удалять поля, будет каждый раз, когда я десериализации Foo x по-прежнему «А»?

ответ

3

Вы не можете удалить поле. См. here at Oracle для совместимых изменений в вашем классе Serializable.

Да после изменения класса Foo десериализация более старого Foo будет устанавливать x в 'A', но поскольку вы удалили поле, это не сработает.

Я предложил сохранить старое поле y и маркировка его @deprecated:

public class Foo implements Serializable { 
    private static final long serialVersionUID = 4068188167994381987L; 
    String x; 
    float f; 
    @deprecated int y; 
} 
1

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

Именно поэтому рекомендуется менять serialVersionUID каждый раз, когда вы вносите изменения, чтобы изменился сериализованный формат класса.

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

0

Я бы использовал «магические» методы сериализации writeObject и readObject для определения настраиваемого потока сериализации. Таким образом, новая версия вашего класса могла бы прочитать старый формат и заполнить новые поля на основе некоторого алгоритма преобразования (здесь читайте значение y int и значение f на нем).

Для получения дополнительной информации о сериализации методов "волшебных", смотрите здесь: http://thecodersbreakfast.net/index.php?post/2011/05/12/Serialization-and-magic-methods

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