java obix_Gson序列化多态对象列表
我认为自定义序列化器/解串器是唯一的方法,我试图向您提出实现它的最紧凑的方法。我为不使用你的类而道歉,但这个想法是一样的(我只想要至少1个基类和2个扩展类)。
BaseClass.java
public class BaseClass{
@Override
public String toString() {
return "BaseClass [list=" + list + ", isA=" + isA + ", x=" + x + "]";
}
public ArrayList list = new ArrayList();
protected String isA="BaseClass";
public int x;
}
ExtendedClass1.java
public class ExtendedClass1 extends BaseClass{
@Override
public String toString() {
return "ExtendedClass1 [total=" + total + ", number=" + number
+ ", list=" + list + ", isA=" + isA + ", x=" + x + "]";
}
public ExtendedClass1(){
isA = "ExtendedClass1";
}
public Long total;
public Long number;
}
ExtendedClass2.java
public class ExtendedClass2 extends BaseClass{
@Override
public String toString() {
return "ExtendedClass2 [total=" + total + ", list=" + list + ", isA="
+ isA + ", x=" + x + "]";
}
public ExtendedClass2(){
isA = "ExtendedClass2";
}
public Long total;
}
CustomDeserializer.java
public class CustomDeserializer implements JsonDeserializer> {
private static Map map = new TreeMap();
static {
map.put("BaseClass", BaseClass.class);
map.put("ExtendedClass1", ExtendedClass1.class);
map.put("ExtendedClass2", ExtendedClass2.class);
}
public List deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
List list = new ArrayList();
JsonArray ja = json.getAsJsonArray();
for (JsonElement je : ja) {
String type = je.getAsJsonObject().get("isA").getAsString();
Class c = map.get(type);
if (c == null)
throw new RuntimeException("Unknow class: " + type);
list.add(context.deserialize(je, c));
}
return list;
}
}
CustomSerializer.java
public class CustomSerializer implements JsonSerializer> {
private static Map map = new TreeMap();
static {
map.put("BaseClass", BaseClass.class);
map.put("ExtendedClass1", ExtendedClass1.class);
map.put("ExtendedClass2", ExtendedClass2.class);
}
@Override
public JsonElement serialize(ArrayList src, Type typeOfSrc,
JsonSerializationContext context) {
if (src == null)
return null;
else {
JsonArray ja = new JsonArray();
for (BaseClass bc : src) {
Class c = map.get(bc.isA);
if (c == null)
throw new RuntimeException("Unknow class: " + bc.isA);
ja.add(context.serialize(bc, c));
}
return ja;
}
}
}
现在这是我为测试整个事情而执行的代码:
public static void main(String[] args) {
BaseClass c1 = new BaseClass();
ExtendedClass1 e1 = new ExtendedClass1();
e1.total = 100L;
e1.number = 5L;
ExtendedClass2 e2 = new ExtendedClass2();
e2.total = 200L;
e2.x = 5;
BaseClass c2 = new BaseClass();
c1.list.add(e1);
c1.list.add(e2);
c1.list.add(c2);
List al = new ArrayList();
// this is the instance of BaseClass before serialization
System.out.println(c1);
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(al.getClass(), new CustomDeserializer());
gb.registerTypeAdapter(al.getClass(), new CustomSerializer());
Gson gson = gb.create();
String json = gson.toJson(c1);
// this is the corresponding json
System.out.println(json);
BaseClass newC1 = gson.fromJson(json, BaseClass.class);
System.out.println(newC1);
}
这是我的执行:
BaseClass [list=[ExtendedClass1 [total=100, number=5, list=[], isA=ExtendedClass1, x=0], ExtendedClass2 [total=200, list=[], isA=ExtendedClass2, x=5], BaseClass [list=[], isA=BaseClass, x=0]], isA=BaseClass, x=0]
{"list":[{"total":100,"number":5,"list":[],"isA":"ExtendedClass1","x":0},{"total":200,"list":[],"isA":"ExtendedClass2","x":5},{"list":[],"isA":"BaseClass","x":0}],"isA":"BaseClass","x":0}
BaseClass [list=[ExtendedClass1 [total=100, number=5, list=[], isA=ExtendedClass1, x=0], ExtendedClass2 [total=200, list=[], isA=ExtendedClass2, x=5], BaseClass [list=[], isA=BaseClass, x=0]], isA=BaseClass, x=0]
一些解释:这个技巧是由串行器/解串器中的另一个Gson完成的。我只使用isA字段来发现正确的类。为了更快,我使用地图将isA字符串与相应的类相关联。然后,我使用第二个Gson对象进行正确的序列化/反序列化。我将其声明为静态,因此您不会通过多次分配Gson来减慢序列化/反序列化。
Pro 你实际上不会编写代码比这更多的代码,你让Gson做所有的工作。您只需记住将新子类放入映射中(异常会提醒您)。
缺点 你有两张地图。我认为我的实现可以稍微改进以避免地图重复,但我把它们留给你(或者将它们留给未来的编辑器,如果有的话)。
也许你想要将序列化和反序列化解析为一个唯一的对象,你应该检查TypeAdapter类或试验一个实现两个接口的对象。
java obix_Gson序列化多态对象列表相关推荐
- java字符串序列化_java对象序列化为字符串
1 场景 java对象某些时候,需要序列化成字符串存储在数据库中,需要的时候,再将字符串反序列化为java对象. 如使用shiro缓存分布式session,需要将session对象序列化成字符串存储在 ...
- java marshal 序列化_marshal 对象的序列化
有时候,要把内存中的一个对象持久化保存到磁盘上,或者序列化成二进制流通过网络发送到远程主机上.Python中有很多模块提供了序列化与反序列化的功能,如:marshal, pickle, cPickle ...
- java字典序列化_Java对象序列化,Serialize Java Data Object,音标,读音,翻译,英文例句,英语词典...
补充资料:对象化 标志人类有目的的对象性活动的过程及其结果的哲学范畴.马克思用这个范畴揭示劳动的实现.劳动物化为对象的事实.劳动的实现意味着创造一定的产品,而劳动的产品就是固定在某个对象中物化为对象的 ...
- java对象序列化去掉字段_使用序列化查找对象中的脏字段
java对象序列化去掉字段 假设您正在开发一个将对象自动保存到数据库中的框架. 您需要检测两次保存之间所做的更改,以便仅保存已修改的字段. 如何检测脏场. 最简单的方法是遍历原始数据和当前数据,并分别 ...
- java图片序列化_Java中的强大武器——对象的序列化
原标题:Java中的强大武器--对象的序列化 所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象.这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象, ...
- JAVA中如何将一个json形式的字符串转为json对象或对象列表
import java.util.*; import java.text.SimpleDateFormat;import org.json.JSONObject; import org.json.JS ...
- Java基础篇:对象拷贝:clone方法 以及 序列化
我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...
- java流与文件——对象流和序列化
[0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--对象流和序列化 的相关知识: 0.2) for source code , pleas ...
- java 编码实现内存拷贝_java提高篇(六)-----使用序列化实现对象的拷贝
我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...
- [转载] java(三)对象的序列化与static、final关键字
参考链接: Java中的final最终变量 java对象的序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程.java中存有Clon ...
最新文章
- MPB:中大李文均组-河口水体和沉积物中微生物的分离培养与鉴定
- 32个程序员萌翻全场的瞬间!
- 生成大小写字母加数字混合ID与自定义进制转换
- C语言的结构使用和结构对齐
- jquery字符串转数组
- 贝叶斯机器学习:经典模型与代码实现
- LY.JAVA面向对象编程.形式参数和返回值
- Java多组输入实现 C++多组输入实现
- mac html flash,苹果电脑flash过期无法打开网页的解决方法
- idea设置主题风格
- 免费网页设计学习课程,视频以及设计工具大全,网页设计不过如此!!!
- 【转】bugku never give up 详解
- gazebo中视觉仿真怎么使用自定义贴图的问题
- nginx实现多个域名在同一服务器指向不同端口
- 关于 DRM 中 DUMB 和 PRIME 名字的由来
- 信创办公–基于WPS的PPT最佳实践系列 (将幻灯片组织成节的形式)
- BiocManager安装R包解决下载速度太慢的问题
- ocp 认证 043
- 万字报告!一文看懂全球车厂的技术家底模块化平台
- apache2 启动、重启、停止方法
热门文章
- linux如何远程装java_使用Shell远程给Linux安装JDK
- html常用代码大全_电子元器件知识资料大全
- [转]余弦cos计算相似度
- Java1.8新特性学习笔记
- 关于for in和for循环的遍历
- java代理模式与反射机制
- 安装Office2007
- android4.4.2 以太网代理,Android2.3.4系统添加Ethernet框架支持
- snmp 获取mac add table_【群晖系统】不拆机不进PE直接修改黑群晖的SN和MAC
- c++输出的值精确到小数点后5位_直击灵魂——圆周率小数点后3位到12411亿位到底有啥用?...