Java Gson:反序列化计算值

Java Gson:反序列化计算值,java,gson,Java,Gson,如何让Gson反序列化计算值 这是一个过于简单的例子: @SerializedName(“成员”) @暴露 非公开最终名单成员; @序列化名称(“大小”) @公开(序列化=真,反序列化=假) 私人最终整数大小; 公共俱乐部(会员名单){ 这个.成员=成员; this.size=members.size(); } 当反序列化为false时,我得到大小=0; 当反序列化为真时,我得到大小=旧大小 有没有办法“强制”重新计算 我知道我可以在getter中这样做,这是因为Gson在反序列化期间不调用构

如何让Gson反序列化计算值

这是一个过于简单的例子:

@SerializedName(“成员”)
@暴露
非公开最终名单成员;
@序列化名称(“大小”)
@公开(序列化=真,反序列化=假)
私人最终整数大小;
公共俱乐部(会员名单){
这个.成员=成员;
this.size=members.size();
}
反序列化
false时,我得到
大小
=0; 当
反序列化
真时,我得到
大小
=旧大小

有没有办法“强制”重新计算


我知道我可以在getter中这样做,这是因为Gson在反序列化期间不调用构造函数。 但是,可以拦截对象后实例化阶段,并对最近反序列化的对象执行一些附加操作

下面是一个示例
@PostConstruct
-感知类型适配器工厂:

最终类后构造类型适配器工厂
实现TypeAdapterFactory{
//没有中间状态,可以是单态
私有静态最终类型适配器工厂postConstructTypeAdapterFactory=新的postConstructTypeAdapterFactory();
私有PostConstructTypeAdapterFactory(){
}
//然而,使构造函数私有化会封装它的实例化方式
静态TypeAdapterFactory getPostConstructTypeAdapterFactory(){
返回构造后类型适配器工厂;
}
@凌驾
公共类型适配器创建(最终Gson Gson、最终TypeToken TypeToken){
最终列表postConstructMethods=getPostConstructMethods(typeToken.getRawType());
if(postConstructMethods.isEmpty()){
//如果没有找到后期构造方法,只需让Gson选择下一个最佳匹配类型适配器本身
返回null;
}
//获取“原始”类型适配器
final-TypeAdapter-delegateTypeAdapter=gson.getDelegateAdapter(这个,typeToken);
返回新的PostConstructTypeAdapter(delegateTypeAdapter,postConstructMethods);
}
私有静态列表getPostConstructMethods(最终类clazz){
if(clazz.isPrimitive()){
//与原语无关
返回空列表();
}
//以下流操作收集所有“@PostConstruct”方法
//从java.lang.Object到具体类
//其中所有@PostConstruct方法必须满足以下条件(不同于原始的@PostConstruct`合同):
//*没有参数
//*不返回任何内容(但看起来限制太严格)
//*用“@PostConstruct”注释`
返回superToSub(clazz)
.stream()
.flatMap(c->Stream.of(c.getDeclaredMethods()))
.过滤器(m->{
final int parameterCount=m.getParameterCount();
如果(参数计数!=0){
返回false;
}
最终类returnType=m.getReturnType();
if(returnType!=void.class){
返回false;
}
返回m.isAnnotationPresent(构造后类);
})
.peek(m->m.setAccessible(true))
.collect(toList());
}
私有静态列表>层次结构=超级分类(clazz);
集合。反向(层次结构);
返回层次;
}
私有静态列表>层次结构=新建ArrayList();
for(类c=clazz;c!=null;c=c.getSuperclass()){
增加(c);
}
返回层次;
}
私有静态最终类PostConstructTypeAdapter
扩展类型适配器{
私有最终类型适配器delegateTypeAdapter;
私人最终可提交的施工后方法;
专用PostConstructTypeAdapter(最终类型Adapter delegateTypeAdapter,最终Iterable postConstructMethods){
this.delegateTypeAdapter=delegateTypeAdapter;
this.postConstructMethods=postConstructMethods;
}
@凌驾
公共无效写入(最终JsonWriter out,最终T值)
抛出IOException{
//写的时候没有什么特别的事情要做,所以就把工作委派给别人吧
delegateTypeAdapter.write(out,value);
}
@凌驾
公共T读(最终JsonReader in)
抛出IOException{
试一试{
//阅读时,需要应用所有施工后方法
最终T read=delegateTypeAdapter.read(in);
对于(最终方法:后构造方法){
方法调用(读取);
}
返回读取;
}捕获(IllegalAccessException | InvocationTargetException ex){
抛出新的IOException(ex);
}
}
}
}
然后,您的
俱乐部可以包含一个post构造函数:

@PostConstruct
构造后的私有void()
抛出NoSuchFieldException、IllegalAccessException{
最终字段大小字段=Club.class.getDeclaredField(“大小”);
sizeField.setAccessible(true);
set(这个,members.size());
}
用于特殊测试的示例:

private static final Gson Gson=new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.registerTypeAdapterFactory(getPostConstructTypeAdapterFactory())
.create();
公共静态void main(最终字符串…参数){
最终名单成员=不可变名单,共有(“Foo”、“Bar”、“Baz”);
俱乐部之前的最终俱乐部=新俱乐部(会员);
beforeClub.members之前的最终列表=beforeClub.members;
最终int beforeSize=beforesclub.size;
最后一个字符串clubJson=gson.toJson(beforeClub);
系统输出打印LN(clubJson);
final Club afterClub=gson.fromJson(clu