我认为自定义序列化器/解串器是唯一的方法,我试图向您提出实现它的最紧凑的方法。我为不使用你的类而道歉,但这个想法是一样的(我只想要至少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序列化多态对象列表相关推荐

  1. java字符串序列化_java对象序列化为字符串

    1 场景 java对象某些时候,需要序列化成字符串存储在数据库中,需要的时候,再将字符串反序列化为java对象. 如使用shiro缓存分布式session,需要将session对象序列化成字符串存储在 ...

  2. java marshal 序列化_marshal 对象的序列化

    有时候,要把内存中的一个对象持久化保存到磁盘上,或者序列化成二进制流通过网络发送到远程主机上.Python中有很多模块提供了序列化与反序列化的功能,如:marshal, pickle, cPickle ...

  3. java字典序列化_Java对象序列化,Serialize Java Data Object,音标,读音,翻译,英文例句,英语词典...

    补充资料:对象化 标志人类有目的的对象性活动的过程及其结果的哲学范畴.马克思用这个范畴揭示劳动的实现.劳动物化为对象的事实.劳动的实现意味着创造一定的产品,而劳动的产品就是固定在某个对象中物化为对象的 ...

  4. java对象序列化去掉字段_使用序列化查找对象中的脏字段

    java对象序列化去掉字段 假设您正在开发一个将对象自动保存到数据库中的框架. 您需要检测两次保存之间所做的更改,以便仅保存已修改的字段. 如何检测脏场. 最简单的方法是遍历原始数据和当前数据,并分别 ...

  5. java图片序列化_Java中的强大武器——对象的序列化

    原标题:Java中的强大武器--对象的序列化 所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象.这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象, ...

  6. JAVA中如何将一个json形式的字符串转为json对象或对象列表

    import java.util.*; import java.text.SimpleDateFormat;import org.json.JSONObject; import org.json.JS ...

  7. Java基础篇:对象拷贝:clone方法 以及 序列化

    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...

  8. java流与文件——对象流和序列化

    [0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--对象流和序列化 的相关知识: 0.2) for source code , pleas ...

  9. java 编码实现内存拷贝_java提高篇(六)-----使用序列化实现对象的拷贝

    我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力,同时拷贝是在内存中进行,在性能方面比我们直接通过new生成对象来的快,特别是在大对象的生成上,使得性能的提升非常 ...

  10. [转载] java(三)对象的序列化与static、final关键字

    参考链接: Java中的final最终变量 java对象的序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程.java中存有Clon ...

最新文章

  1. MPB:中大李文均组-河口水体和沉积物中微生物的分离培养与鉴定
  2. 32个程序员萌翻全场的瞬间!
  3. 生成大小写字母加数字混合ID与自定义进制转换
  4. C语言的结构使用和结构对齐
  5. jquery字符串转数组
  6. 贝叶斯机器学习:经典模型与代码实现
  7. LY.JAVA面向对象编程.形式参数和返回值
  8. Java多组输入实现 C++多组输入实现
  9. mac html flash,苹果电脑flash过期无法打开网页的解决方法
  10. idea设置主题风格
  11. 免费网页设计学习课程,视频以及设计工具大全,网页设计不过如此!!!
  12. 【转】bugku never give up 详解
  13. gazebo中视觉仿真怎么使用自定义贴图的问题
  14. nginx实现多个域名在同一服务器指向不同端口
  15. 关于 DRM 中 DUMB 和 PRIME 名字的由来
  16. 信创办公–基于WPS的PPT最佳实践系列 (将幻灯片组织成节的形式)
  17. BiocManager安装R包解决下载速度太慢的问题
  18. ocp 认证 043
  19. 万字报告!一文看懂全球车厂的技术家底模块化平台
  20. apache2 启动、重启、停止方法

热门文章

  1. linux如何远程装java_使用Shell远程给Linux安装JDK
  2. html常用代码大全_电子元器件知识资料大全
  3. [转]余弦cos计算相似度
  4. Java1.8新特性学习笔记
  5. 关于for in和for循环的遍历
  6. java代理模式与反射机制
  7. 安装Office2007
  8. android4.4.2 以太网代理,Android2.3.4系统添加Ethernet框架支持
  9. snmp 获取mac add table_【群晖系统】不拆机不进PE直接修改黑群晖的SN和MAC
  10. c++输出的值精确到小数点后5位_直击灵魂——圆周率小数点后3位到12411亿位到底有啥用?...