У меня есть несколько полиморфных c java классов, которые я сериализую / десериализую. Я использую RuntimeTypeAdapterFactory из Gson-extras, чтобы обеспечить правильную сериализацию и десериализацию классов с полем «type», установленным на имя производного класса. Это работает нормально.
У меня есть некоторые другие классы, которые я сериализую / десериализирую, у которых есть некоторые переменные с примененным модификатором переходного процесса. Я использую PostConstructAdapterFactory, также из Gson-extras, чтобы добавить метод PostConstruct в мои классы, чтобы значения переходных переменных могли быть переназначены после завершения десериализации и до вызова любой из функций в классах. Это также работает нормально.
Проблема, с которой я столкнулся, заключается в том, что у меня есть другая группа классов, которые являются полиморфными c, а также имеют временные переменные, где я хотел бы, чтобы метод PostConstruct выполнялся после десериализации. Все мои попытки использовать одновременно RuntimeTypeAdapterFactory и PostConstructAdapterFactory не увенчались успехом. Я могу зарегистрировать и то и другое, но когда я это делаю, поведение PostConstructAdapterFactory, кажется, перезаписывает поведение RuntimeTypeAdapterFactory, в результате чего мои классы больше не сохраняют поле «тип», необходимое для классов polymorphi c.
Кажется, я могу иметь одно или другое, но не оба. Я даже смотрел на написание гибридного класса AdapterFactory с возможностями обеих фабрик адаптеров, но это тоже было неудачно.
Я чувствую, что здесь может быть упущено что-то очевидное в том, как они спроектированы. Конечно, можно заставить обе части функциональности работать вместе для моих классов? Ниже приведен простой пример, демонстрирующий то, что я говорю.
public class BaseClass {
private static final RuntimeTypeAdapterFactory<BaseClass> ADAPTER = RuntimeTypeAdapterFactory.of(BaseClass.class);
private static final HashSet<Class<?>> REGISTERED_CLASSES= new HashSet<Class<?>>();
static { GsonUtils.registerType(ADAPTER); }
private synchronized void registerClass() {
if (!REGISTERED_CLASSES.contains(this.getClass())) {
REGISTERED_CLASSES.add(this.getClass());
ADAPTER.registerSubtype(this.getClass());
}
}
public BaseClass() {
registerClass();
}
}
public class DerivedClass extends BaseClass {
public DerivedClass(Integer number) {
super();
this.number = number;
Init();
}
protected Integer number;
protected transient Integer doubled;
protected transient Integer tripled;
protected transient Integer halved;
protected transient Integer squared;
protected transient Integer cubed;
public void Init() {
halved = number / 2;
doubled = number * 2;
tripled = number * 3;
squared = number * number;
cubed = number * number * number;
}
@PostConstruct
private void postConstruct() {
Init();
}
}
public class GsonUtils {
private static final GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapterFactory(new PostConstructAdapterFactory());
public static void registerType(RuntimeTypeAdapterFactory<?> adapter) {
gsonBuilder.registerTypeAdapterFactory(adapter);
}
public static Gson getGson() {
return gsonBuilder.create();
}
}
Gson gson = GsonUtils.getGson();
String serialized = gson.toJson(new DerivedClass(6), BaseClass.class);
DerivedClass dc = gson.fromJson(serialized, DerivedClass.class);
Обновление: спасибо за ответ @ michał-ziober. Выполнение, как вы сказали, действительно сработало. Это действительно отвечает на вопрос, однако, это все еще точно не решает мою проблему. Позвольте мне немного изменить вопрос.
Упрощенная версия моего кода была, пожалуй, слишком простой. Когда я пытаюсь сериализовать / десериализовать DerivedClass как свойство другого класса, моя первоначальная проблема высвечивается. Как показано ниже:
public class WrapperClass {
protected BaseClass dc = new DerivedClass(6);
}
Gson gson = GsonUtils.getGson();
String serialized = gson.toJson(new WrapperClass());
WrapperClass wc = gson.fromJson(serialized, WrapperClass.class);
В этом сценарии, пока мой DerivedClass не определяет метод PostConstruct, сериализация / десериализация DerivedClass работает нормально. Но если это так, свойство "type" не записывается в файл.
Просто для повторения, если я сериализую / десериализую DerivedClass напрямую, все нормально, но если он внутри WrapperClass и я сериализую / десериализуем WrapperClass И если я определю метод PostConstruct, он не будет работать.