博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Gson关于抽象类的序列化与反序列化
阅读量:4360 次
发布时间:2019-06-07

本文共 3512 字,大约阅读时间需要 11 分钟。

Gson关于抽象类的序列化与反序列化

背景知识

Gson是Google推出的Java对象与Json对象的之间转换的Java类库,需要将Java对象序列化时,使用 

A a = new A();     // Java对象序列化成String  Gson gson = new Gson();    // String 反序列成Java对象     String jsonStr = gson.toJson(a);     A res = gson.fromJson(jsonStr, A.class);

  

问题背景

我需要将一个Java对象转成json对象进行持久化,在序列化工具中,我们知道gson是一个代码量少,简洁并且快速的Java类库,由此我选择了它进行序列化,但是其中发现一个问题:gson没有办法去将一个抽象类反序列化出来,并且在序列化的时候还不会报错,下面直接上代码: 首先给出我们需要序列化的类们: 抽象类:

public abstract class BaseBO implements Serializable {    private String name;    private Integer age;}

  

baseBO的继承类:

public class Person extends BaseBO {    private Boolean sex;    private String address;}

  

测试类:

public static void main(String[] args) {        Gson gson = new Gson();        BaseBO baseBO = new Person();        baseBO.setName("emma");        baseBO.setAge(100);        String jsonString = gson.toJson(baseBO, BaseBO.class );        BaseBO res = gson.fromJson(jsonString, BaseBO.class);        System.out.println(res);    }

  

运行后报错,报错信息如下:

Exception in thread "main" java.lang.RuntimeException: Failed to invoke public com.alibaba.test.BaseBO() with no args    at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:111)    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:210)    at com.google.gson.Gson.fromJson(Gson.java:888)    at com.google.gson.Gson.fromJson(Gson.java:853)    at com.google.gson.Gson.fromJson(Gson.java:802)    at com.google.gson.Gson.fromJson(Gson.java:774)    at com.alibaba.test.TestApplication.main(TestApplication.java:17)Caused by: java.lang.InstantiationException    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)    at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:108)    ... 6 more

  

说明:从上面这段报错信息可以看出,gson不能序列化一个抽象类,因为抽象类没有办法使用构造函数去构造出来,所以他没办法序列化,那我们如果需要对存在baseBO的类进行序列化呢?我们需要一个适配器,在序列化的时候将抽象类使用的继承类的类名存下来,然后在反序列化的时候指定他的实现类,就像这样:

public class BaseBoAdapter implements JsonSerializer
, JsonDeserializer
{ @Override public BaseBO deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); String type = jsonObject.get("type").getAsString(); JsonElement element = jsonObject.get("properties"); try { // 指定包名+类名 String thePackage = "org.test."; return context.deserialize(element, Class.forName(thePackage + type)); } catch (ClassNotFoundException cnfe) { throw new JsonParseException("Unknown element type: " + type, cnfe); } } @Override public JsonElement serialize(BaseBO src, Type typeOfSrc, JsonSerializationContext context) { JsonObject result = new JsonObject(); result.add("type", new JsonPrimitive(src.getClass().getSimpleName())); result.add("properties", context.serialize(src, src.getClass())); return result; }}

  

需要实现JsonSerializerJsonDeserializer中的序列化和反序列的方法,然后在new Gson()的时候将这个适配器注册进去,就像这样:

Gson gson = new GsonBuilder()            .registerTypeAdapter(BaseBO.class, new BaseBoAdapter())            .create();

  

然后,你就可以得到正确的结果了,如下:

org.test.Person@62043840[name=emma,age=100]Process finished with exit code 0

  

转载于:https://www.cnblogs.com/Gabby/p/10263389.html

你可能感兴趣的文章
Thread
查看>>
char * 与char []探究理解
查看>>
QT窗体显示在屏幕中间位置
查看>>
emmet使用技巧
查看>>
RPC-Thrift(二)
查看>>
MSSQL for Linux 安装指南
查看>>
【Golang 接口自动化08】使用标准库httptest完成HTTP请求的Mock测试
查看>>
前端必读:浏览器内部工作原理
查看>>
Uri、URL和URN三者的区别
查看>>
数据字典的转换
查看>>
关于动态添加iview admin路由以及刷新侧边栏
查看>>
ApplicationInsights的探测器尝鲜
查看>>
java 解析Json格式数据
查看>>
unix中的线程池技术详解
查看>>
CSS简介
查看>>
常用三大软件评价1
查看>>
MVC各层介绍使用---初步理解
查看>>
单例对象的创建与销毁
查看>>
知识点关键词(记录一下)
查看>>
国际结算业务
查看>>