当Java泛型类型擦除遇到JSON序列化和反序列化

目录

  • 当Java泛型类型擦除遇到JSON序列化和反序列化
    • 前言
    • 测试

前言

-最近看到了Spring 关于 RestTemplate的源码实现又有了一些思考,突然想到之前自己处理过这样的场景,这次整理一篇文章水一下子,哈哈哈哈。先抛出问题:

  • 如果让你让对复杂JSON对象转为Java Bean你会怎么写?
  • -要转换的Java Bean 中有泛型,又要怎么转?

本次重点我们放在JSON 反序列化时如何正确告诉Java 运行时,泛型中具体的类型是什么。

测试

源于工作中遇到的一个场景,使用httpClient 调用其他服务的接口,想要把Response 的body 中的JSON 格式的字符串反序列化为Java Bean。

  • 测试用的Java Bean:
class TestBean {private String name;private String code;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}@Overridepublic String toString() {return "TestBean{" +"name='" + name + '\'' +", code='" + code + '\'' +'}';}
}
  • 青铜
    public static void main(String[] args) {JSONObject jsonObject = new JSONObject();jsonObject.put("name", "aaa");jsonObject.put("code", "123");TestBean testBean = JSONObject.toJavaObject(jsonObject, TestBean.class);System.out.println(testBean);}

控制台打印:

TestBean{name='aaa', code='123'}
  • 黄金
    这次在TestBean 添加属性 List<T> listBean;

public class Test1 {public static void main(String[] args) {/*  JSONObject jsonObject = new JSONObject();jsonObject.put("name", "aaa");jsonObject.put("code", "123");TestBean testBean = JSONObject.toJavaObject(jsonObject, TestBean.class);System.out.println(testBean);*/JSONObject jsonObject = new JSONObject();jsonObject.put("name", "aaa");jsonObject.put("code", "123");JSONObject a = new JSONObject();a.put("id", 1);a.put("name", "属性a");JSONArray array = new JSONArray();array.add(a);jsonObject.put("listBean", array);TestBean<A> testBean = JSONObject.toJavaObject(jsonObject, TestBean.class);System.out.println(testBean);}
}class TestBean<T> {private String name;private String code;List<T> listBean;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public List<T> getListBean() {return listBean;}public void setListBean(List<T> listBean) {this.listBean = listBean;}@Overridepublic String toString() {return "TestBean{" +"name='" + name + '\'' +", code='" + code + '\'' +", listBean=" + listBean +'}';}
}class A {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "A{" +"id=" + id +", name='" + name + '\'' +'}';}
}

控制台打印:

TestBean{name='aaa', code='123', listBean=[{"name":"属性a","id":1}]}
  • 遇到了绊脚石
    我们打印一下 listBean 集合中对象的属性name
System.out.println(testBean.getListBean().get(0).getName());

控制台报错:

Exception in thread "main" java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.zhw.free.zhwfreedemo.testjson.Aat com.zhw.free.zhwfreedemo.testjson.Test1.main(Test1.java:30)

报了类转换异常,提示JSONObject 无法转换为我们刚刚定义的A,这是为什么呢?

  • Debug看一下究竟

原来JSONObject帮我们反序列化后,集合中依然是JSONObject。这里就要说说Java 的泛型的类型擦除了。

在反序列化为TestBean的时候,JSONObject并不知道listBean集合中存放的类型是什么,但是依然可以转换成功。这就是泛型的类型擦除的功劳。泛型的类型擦除机制方便了我们,但也给我们反序列化时留下了思考,如何让JSON反序列化时知道我们泛型中的类型是什么呢?

  • 王者
        TestBean<A> result = jsonObject.toJavaObject(new TypeReference<TestBean<A>>() {});System.out.println(result);System.out.println(result.getListBean().get(0).getName());

利用TypeReference 指定泛型中的类型, 就可以顺利反序列化成功,并且 集合中的对象也转换过来了。

当Java泛型擦除遇到JSON序列化和反序列化相关推荐

  1. java 获取泛型_聊聊Java泛型擦除那些事

    >版权申明]非商业目的注明出处可自由转载 博文地址:https://blog.csdn.net/ShuSheng0007/article/details/89789849 出自:shushen ...

  2. JAVA中JSON序列化和反序列化

    JAVA中JSON序列化和反序列化 1 FASTJSON的序列化和反序列化 1.1 主函数 1.2 自定义对象 2 GSON序列化和反序列化 2.1 主函数 2.2 自定义对象 总结 不同包序列化和反 ...

  3. 一文读懂Json序列化与反序列化

    一文读懂Json序列化与反序列化 一文读懂Json序列化与反序列化 #mermaid-svg-tVjnnlFu6ZBDpGOQ {font-family:"trebuchet ms" ...

  4. JSON序列化和反序列化还有这种玩法

    Mixin对于前端开发者可不陌生,Vue.React等知名前端框架都使用了Mixin.而对于后端开发,尤其是Java后端开发来说Mixin却是一个很陌生的概念.今天来我们通过Jackson让后端开发者 ...

  5. json 反序列化 父子类型_Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo...

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...

  6. 序列化对象C++对象的JSON序列化与反序列化探索

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 一:背景 作为一名C++开发人员,我始终很期待能够像C#与JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找 ...

  7. JSON序列化和反序列化

    1.什么是json序列化和反序列化? json序列化:就是JavaBean对象转化为JSON格式的字符串. 反序列化:就是序列化的反方向,将字符串转化为JavaBean. 2.为什么要序列化和反序列化 ...

  8. LocalDateTime的JSON序列化和反序列化

    jackson的json中Date的序列化和反序列化 import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jac ...

  9. DotNet的JSON序列化与反序列化

    JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...

最新文章

  1. 使用 Portainer UI 管理 Docker 主机
  2. CTFshow 命令执行 web29
  3. vue小米商城源代码_微信商城信息管理系统(java后台+小程序)
  4. 应用层组播、IP组播
  5. Java 位运算和逻辑运算的区别
  6. 记录一次IDEA开发JavaWeb项目时JS中文乱码排错方法
  7. java中paint_java中paint()的具体用法是什么?
  8. 程序员不会SQL有多难?高级工程师:可能工作都找不到!
  9. 吴江智慧城市产业化“航母”起航
  10. 学校校园无盘教学系统
  11. 软件保护技术 - 基础
  12. 怎样学构图-平面设计中有哪几项构图
  13. 20172307 / 20172311 结对编程项目-四则运算 第三周总结
  14. MTCNN中的IOU详解
  15. python中的框架是什么_python开发框架介绍
  16. Ubuntu设置屏幕分辨率
  17. 【Android实战】保存QQ账号与密码
  18. uniapp连接到微信小程序调试全过程以及遇到的bug
  19. react根据中文获取拼音_解决 React 中的 input 输入框在中文输入法下的 bug
  20. 51Nod - 1298

热门文章

  1. Spring 中的切点表达式介绍
  2. java切点类编写_SpringAOP切点函数实现原理详解
  3. MobaXterm 终端界面 修改背景颜色
  4. 机器视觉3:光度立体技术
  5. eos源码分析和应用(一)调试环境搭建
  6. TabLayout使用介绍(com.google.android.material.tabs.TabLayout)
  7. 《微信小程序-进阶篇》Lin-ui组件库源码分析-列表组件List(一)
  8. Echarts3实例 双Y轴折线图
  9. 手机中的RF射频芯片和基带芯片的区别和联系
  10. QMUI系列(1):引入、设置主题、基本使用