直男码农傲娇求赞求评论~^_^~

假设有个User类,我们想用Gson将一个字符串解析成User类,那么可以像下面这样,比较简单:

Gson gson = new Gson();
User user = gson.fromJson("user对象json字符串",User.class)

但是如果是一个User数组的字符串呢,我们希望解析成List<User> 类型的一个数组

这个List<User>不能直接.class,我们可以用下面这个方法

public <T> T fromJson(String json, Type typeOfT){
}

然后这里的 Type typeOfT,即List<User> 的Type 如何获取呢?

可以这样:(利用Gson库中的TypeToken类)就可以获取到List<User> 的Type,进而完成解析

Type type = new TypeToken<List<User>>(){}.getType();

那么TypeToken内部究竟是如何做的呢?下面请看源码

public class TypeToken<T> {final Class<? super T> rawType;final Type type;final int hashCode;/*** Gets underlying {@code Type} instance.*/public final Type getType() {return type;}//protected 修饰符不能在外部直接new对象/*** Constructs a new type literal. Derives represented class from type* parameter.** <p>Clients create an empty anonymous subclass. Doing so embeds the type* parameter in the anonymous class's type hierarchy so we can reconstitute it* at runtime despite erasure.*/@SuppressWarnings("unchecked")protected TypeToken() {this.type = getSuperclassTypeParameter(getClass());this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);this.hashCode = type.hashCode();}
//默认修饰符 不能在外部直接new对象/*** Unsafe. Constructs a type literal manually.*/@SuppressWarnings("unchecked")TypeToken(Type type) {this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);this.hashCode = this.type.hashCode();}/*** Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize* canonical form}.*/static Type getSuperclassTypeParameter(Class<?> subclass) {
//注意注意,这句话比较重要,这个是获取父类的带泛型的Class对象
//因为构造方法已经不能直接用于在外部直接new对象,所以在外部只能通过子类的方式来构造对象
//而匿名内部类就是一个对该类的继承方式
//通过匿名内部类的方式得到一个对象,通过该对象getClass.getGenericSuperclass()方法
//获取到父类的带泛型的Class对象,就是TypeToken 本身了Type superclass = subclass.getGenericSuperclass();if (superclass instanceof Class) {throw new RuntimeException("Missing type parameter.");}
//因为TypeToken上定义了泛型,在外部使用时传了具体的类型,
//获取的genericSuperclass就是ParameterizedType
//进而通过ParameterizedType的getActualTypeArguments方法获取实际的泛型数组
//因为TypeToken类上只定义了一个泛型参数,所以这里获取的Type[]大小就是1了
//直接[0],就获取到了传入的实际类型Type,即传入的List<User>ParameterizedType parameterized = (ParameterizedType) superclass;
//canonicalize 看字面是规范化的意思,内部主要是Gson将Java jdk中Type的各个实现类转换成了Gson自
//己对Type的各个实现类 (测试发现不调用这个方法也能对数组类型的字符串也能解析成功)return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);}
//省略代码。。。。
}

关于Type 和 ParameterizedType

Type 有 5个子类/接口,其中一个就是 ParameterizedType

而 ParameterizedType 里有三个方法

直接举例,如果是List<User> 那么Type[] 就是[User],
如果是Map<Integer,String>,那么Type[] 就是[Integer,String]
如果是HashMap<Integer,List<User>>,那么Type[]就是[Integer,List<User>]
总之,就是获取最外层<>里面的内容

Type[] getActualTypeArguments();

举例:如果是List<User> 那么Type 就是List,
如果是Map<Integer,String>,那么Type 就是Map
如果是HashMap<Integer,List<User>>,那么Type[]就是HashMap

Type getRawType();
Type getOwnerType();

关于Type更多内容可以参考

https://www.jianshu.com/p/e8eeff12c306

Gson TypeToken 原理解析相关推荐

  1. Gson源码解析和它的设计模式

    前言 之前一段时间,准备把糗百的项目中json解析的模块中的原生Json解析换成gson解析,工作比较繁杂,坑多,因此为了防止出错,我还对Gson做了一个源码分析.这一篇就是Gson源码分析的总结,同 ...

  2. Json、Gson、FAST-JSON解析学习

    Json JavaScript Object Notation javascript表示对象的一种方式 基于JavaScript语言的轻量级的数据交换格式;即:用来传输数据的一种格式.不管是web应用 ...

  3. Jetpack Room 使用及原理解析

    深入学习 Jetpack 系列的 Android Architecture Components 中的一些列组件,记录一下学习过程,本文是 Room 的使用及原理解析,通过一个实际的例子,来体验 Ro ...

  4. Andorid中使用Gson和Fast-json解析库解析JSON数据---第三方库学习笔记(二)

    JSON介绍: JSON:JavaScript对象表示法 JSON是存储和交换文本信息的语法. 特点: JSON是轻量级的文本数据交换格式 JSON独立于语言和平台 JSON具有自我描述性,更易理解 ...

  5. Retrofit2 工作原理解析(一)

    Retrofit2 工作原理解析(一) 概述 Retrofit是square公司开源的一款类型安全的http请求框架,用于Java和Android程序.Retrofit可以说是restful风格的一个 ...

  6. Spark Shuffle原理解析

    Spark Shuffle原理解析 一:到底什么是Shuffle? Shuffle中文翻译为"洗牌",需要Shuffle的关键性原因是某种具有共同特征的数据需要最终汇聚到一个计算节 ...

  7. 秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

    2019独角兽企业重金招聘Python工程师标准>>> 上节概要: 上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六)  中, 介绍了 ...

  8. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  9. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

最新文章

  1. 1月31日云栖精选夜读:阿里云客户案例研究:罗辑思维
  2. python编程基础知识体系_最新版 17 幅思维导图:Python 编程之核心知识体系
  3. 为网站文字前面添加图标 在线调用 Font Awesome 字体icon小图标 美化网站
  4. cloudstack4.11 centos7 安装文档
  5. 同时画多个饼图_手帐术 | 这个神奇饼图里,藏着时间管理的小秘诀
  6. uni-app微信小程序登录;uni-app微信登录小程序;uni-app微信登录app;
  7. 机动车c1科三考试语言灯光,c1科目三灯光模拟考试
  8. django安装配置及测试
  9. fluent加载第三方(C++,Fortan等)动态链接库
  10. php 修复excel 乱码,php下载excel乱码的解决方法
  11. Android设备给Android设备刷固件
  12. 计算机做无线AP共享文件,Windows 7妙用 笔记本变无线AP轻松共享
  13. 区块链技术正大肆颠覆价值数十亿美元的金融科技产业
  14. RuntimeError:The size of tensor a (100) must match the size of tensor b (12800) at non-singleton di
  15. LittleVGL体验记录
  16. 微信小程序开发之小米商城
  17. Git 工具 - 储藏(Stashing) git stash 暂存现在工作区的内容
  18. 【鼠标移入暂停animation动画】
  19. 写程序关键是真正自己开始动手写,不要总是想着等全部弄懂了再写
  20. [再寄小读者之数学篇](2014-11-02 Herglotz' trick)

热门文章

  1. C语言中string函数库中的一些函数的用法
  2. [RK3568 Android12] GT911触摸屏调试
  3. html手机端自适应头部,html5写自适应头部
  4. iOS 时间比较大小
  5. 初中计算机活动策划方案,信息技术中考备考方案
  6. 无惧管控放开,分享居家办公、远程办公项目经验
  7. Python——柱状图(条形图、堆叠图)
  8. 关于ORA-01122,ORA-01110,ORA-01203的解决方案
  9. 科士达STATIONAIR系列精密空调远程监控解决方案
  10. sh文件、shell、shell脚本、bat文件、bat脚本