gson关于抽象类的序列化与反序列化(代码片段)

gabby gabby     2023-02-22     751

关键词:

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<BaseBO>, JsonDeserializer<BaseBO> 

    @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();

  

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

[email protected][name=emma,age=100]

Process finished with exit code 0

  

mfc文件的读写操作,类的序列化与反序列化,cfile,cfiledialog,carchive,cstdiofile(代码片段)

一,使用CFileDialog文件对话框对话框仅仅是为了获得将要打开文件或保存文件的名称和路径,当然还会有文件的后缀过滤器。代码如下: /*打开文件对话框*/ CStringfilter;//MFC的字符串类 filter="文本文档(*.txt)|*.txt||&... 查看详情

android中使用gson完成对象的序列化与反序列化

前言:JSON(JavaScriptObjectNotation):是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。具体的JSON数据格式内容如:["id":"5","version":"1.0","name":"Android","id":"6","version":"2.0","name":"JAVA","id":"7","version":"3.0","name":" 查看详情

序列化与反序列化(代码片段)

串行化是指存储和获取磁盘文件、内存或其他地方中的对象。在串行化时,所有的实例数据都保存到存储介质上,在取消串行化时,对象会被还原,且不能与其原实例区别开来。只需给类添加Serializable属性,... 查看详情

序列化组件serializer之序列化与反序列化(代码片段)

一、知识补充1、序列化与反序列化"""1)序列化组件单表序列化(后台数据返回给前台):将后台的数据对象,转换成能用于网络传输的过程,即又是将对象转换成二进制字符串单表反序列化(前台提交数据给后台):拿内存的数据转... 查看详情

kotlin中json的序列化与反序列化--gsonmoshi(代码片段)

文章目录Kotlin中Json的序列化与反序列化--Gson、Moshi实体类集成方式GsonMoshi非空类型序列化反序列化结论可空类型序列化反序列化结论总结Kotlin中Json的序列化与反序列化–Gson、Moshi在App的开发中避免不了需要和Json格式的数据打交... 查看详情

内部类,drf响应类,序列化与反序列化(代码片段)

...alizer(serializers.ModelSerializer):classMeta:model="Book"#配置序列化类绑定的Model表DRF响应类:Response"""def__init__(self,data=None,status=None,template_name=None,headers=None,exception=False,content_type=None):passdata:响应的数据-空、字符串、数... 查看详情

xml序列化与反序列化工具(代码片段)

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.IO;usingSystem.Xml.Serialization;usingSystem.Xml;namespaceConsoleApplication1///<summary>///xml序列化与反序列化 查看详情

serializable接口序列化与反序列化(代码片段)

...的目的是为了可持久化,比如网络传输或本地存储。实现序列化很简单:1publicclassPersonimplementsSerializable2privateStringname;3/*name属性的getter/setter方法省略*/4 这里以Java消息服务方式传递该对象(即通过网络传递一个对象),定义在消... 查看详情

序列化与反序列化(代码片段)

序列化和反序列化的三种方法:1.使用JavaScriptSerializer类2.使用DataContractJsonSerializer类3.使用JSON.NET类库第一种方法://使用JavaScriptSerializer方式需要引入的命名空间,这个在程序集System.Web.Extensions.dll.中usingSystem.Web.Script.Serialization;1.... 查看详情

java对象序列化与反序列化(代码片段)

引言    在学习IO流时,我们会学到一个序列化流,和反序列化流,相信不少小伙伴学到这个是有些懵的,今天就带大家来了解一下java的对象序列化流与反序列化流  目录一、什么是java的对象序列化流与反序列... 查看详情

算法19:leetcode_二叉树序列化与反序列化(层序)(代码片段)

...eetcode.cn/problems/serialize-and-deserialize-binary-tree/**二叉树按层序列化与反序列化**/publicclassCode01_SerializeAndReconstructTreestaticclassTreeNodeintval;TreeNodeleft;TreeNoderight;TreeNode(intx)val=x;publicstaticfinalStringSEPARATOR=",";publicStringserialize(TreeNoderoot)//边界... 查看详情

jsonutils序列化与反序列化工具(代码片段)

直接见代码,需要引入的包如下文,需要谷歌的包。1packagecom.cxf.value;23importcom.fasterxml.jackson.core.type.TypeReference;4importcom.fasterxml.jackson.databind.DeserializationFeature;5importcom.fasterxml.jackson.databind.Ob 查看详情

io流--序列化流与反序列化流(代码片段)

IO流--序列化流与反序列化流:  序列化流:把对象当做流一样写入到文本文件中ObjectOutputSream();  反序列化流:把文本文件中的流对象还原成对象ObjectInputSream(); 具体的使用: 1  创建java对象实现序... 查看详情

fastjson序列化与反序列化(代码片段)

...个类是fastjsonAPI的入口,主要的功能都通过这个类提供。序列化API//将Java对象序列化为JSON字符串,支持各种各种Java基本类型和JavaBeanpublicstaticStringtoJSONString(Objectobject,SerializerFeature...features);//将Java对象序列化为JSON字符串,返回JSO... 查看详情

java编程基础-序列化与反序列化(代码片段)

序列化ObjectOutputStream类将对象数据序列化,保存到文件中构造方法ConstructorObjectOutPutStream(OutputStreamout);输出字节流对象作为当前方法的参数新建Person类作为实例:packagecn.ocean888;importjava.io.Serializable;//如果一个类需要序列化,则需要遵... 查看详情

golanggo语言json的序列化与反序列化实践(代码片段)

Go语言JSON的序列化与反序列化实践导读本文使用Go原生支持的包,对JSON字符串以及.json文件进行序列化与反序列化实践。使用到的包是encoding/json。详细文档可查看官方中文文档,链接为:https://studygolang.com/pkgdoc本文中... 查看详情

序列化与反序列化(代码片段)

...ngSystem.IO;//usingSystem.Runtime.Serialization.Formatters.Binary;namespace序列化与反序列化classProgrampublicstaticvoidMain(String[]args)//序列化//Personp=newPerson();//p.Name="张三";//p.Age=20;//p.Gender=‘f‘;//using(FileStreamfswrite=newFileStream(@"f:Person.txt",FileMode.CreateNew... 查看详情

序列化serialize()与反序列化unserialize()的实例(代码片段)

在写序列化serialize与反序列化unserialize()时,我们先来看看:serialize—产生一个可存储的值的表示描述stringserialize(mixed$value)serialize()返回字符串,此字符串包含了表示value的字节流,可以存储于任何地方。这有利于存储或传递PHP的... 查看详情