栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Gson序列化多态对象列表

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Gson序列化多态对象列表

我认为自定义序列化器/反序列化器是继续进行的唯一方法,我尝试向您建议实现我发现的最紧凑的方法。对于没有使用您的类,我深表歉意,但是想法是一样的(我只想要至少1个基类和2个扩展类)。

baseClass.java

public class baseClass{    @Override    public String toString() {        return "baseClass [list=" + list + ", isA=" + isA + ", x=" + x + "]";    }    public ArrayList<baseClass> list = new ArrayList<baseClass>();    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<List<baseClass>> {    private static Map<String, Class> map = new TreeMap<String, Class>();    static {        map.put("baseClass", baseClass.class);        map.put("ExtendedClass1", ExtendedClass1.class);        map.put("ExtendedClass2", ExtendedClass2.class);    }    public List<baseClass> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {        List list = new ArrayList<baseClass>();        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<ArrayList<baseClass>> {    private static Map<String, Class> map = new TreeMap<String, Class>();    static {        map.put("baseClass", baseClass.class);        map.put("ExtendedClass1", ExtendedClass1.class);        map.put("ExtendedClass2", ExtendedClass2.class);    }    @Override    public JsonElement serialize(ArrayList<baseClass> 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<baseClass> al = new ArrayList<baseClass>();  // 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
类或尝试使用同时实现两个接口的对象。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/437061.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号