【发布时间】:2020-05-05 16:28:47
【问题描述】:
我有一些我正在序列化/反序列化的多态 Java 类。我正在使用 Gson-extras 中的 RuntimeTypeAdapterFactory 来确保类正确序列化和反序列化,并将“类型”字段设置为派生类的名称。它工作正常。
我有一些其他的类,我正在序列化/反序列化,它们有一些应用了瞬态修饰符的变量。我正在使用同样来自 Gson-extras 的 PostConstructAdapterFactory 将 PostConstruct 方法添加到我的类中,以便可以在反序列化完成后和调用类中的任何函数之前重新分配瞬态变量的值。这也很好用。
我面临的挑战是我有另一组多态类,也有瞬态变量,我希望在反序列化后执行 PostConstruct 方法。我所有同时使用 RuntimeTypeAdapterFactory 和 PostConstructAdapterFactory 的尝试都失败了。我可以注册两者,但是当我这样做时, PostConstructAdapterFactory 行为似乎覆盖了 RuntimeTypeAdapterFactory 行为,导致我的类不再存储多态类所需的“类型”字段。
似乎我可以选择其中之一,但不能同时拥有。我什至考虑编写一个具有两种适配器工厂功能的混合适配器工厂类,但也没有成功。
我觉得我可能在这里遗漏了一些关于这些设计方式的明显内容。当然可以让我的课程同时使用这两个功能吗?下面是一个简单的例子来说明我在说什么。
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 的序列化/反序列化就可以正常工作。但如果是这样,“类型”属性不会写入文件。
重申一下,如果我直接序列化/反序列化 DerivedClass,一切都很好,但如果它在 WrapperClass 中并且我序列化/反序列化 WrapperClass 并且如果我定义了 PostConstruct 方法,则它不起作用。
【问题讨论】:
标签: java serialization polymorphism gson postconstruct