2016-07-22 2 views
1

Мой неизменяемый класс (все поля final) содержит ссылку на объект стороннего класса, который не реализует Serializable. Обычным обходным решением для этого является (как описано в ответе на прием How to serialize a non-serializable in Java?), чтобы использовать методы writeObject и readObject для создания пользовательского формата сериализации. Однако readObject не может обновить поля final, потому что это не конструктор. Я видел suggestion, используя readResolve, чтобы обойти это, но не могу понять, как это может работать, потому что я не вижу, как получить данные, необходимые для инициализации конечного поля в этом методе (по-видимому, он имеет доступ только к поля, которые я уже инициализировал, и я бы предпочел не создавать новое изменяемое поле в объекте для временного использования во время десериализации, когда объект должен быть полностью неизменным). Итак, как я могу заставить десериализацию работать?Как сериализовать конечное поле, содержащее объект, не связанный с сериализацией

public class ThisDoesntWork implements Serializable 
{ 
    private final transient SomeNonSerializableClass object; 
    private void writeObject (ObjectOutputStream out) throws IOException 
    { 
     out.writeUTF (object.toString()); 
    } 
    private void readObject (ObjectInputStream in) throws IOException 
    { 
     object = SomeNonSerializableClass.fromString(in.readUTF()); // error! 
    } 
} 
+0

Вы можете просто удалить ключевое слово 'final'. Ваш класс по-прежнему остается неизменным, даже если вы его удалите, потому что вы контролируете весь доступ к полю. Вот почему вы инкапсулируете поля. Вы можете оставить «final» в качестве комментария для целей документации, например. 'private/* final */MyObject myObj'. – Andreas

ответ

2

Вы можете использовать writeReplace() написать объект в другом (прокси) класса и readResolve() к конструкт объект исходного класса из значений в прокси. Конструктор может установить конечное поле.

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