【26】Gson原理

2023-05-16

(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

Gson原理

文章目录

  • Gson原理
    • 1.Gson原理
      • 1.1json分析
        • 1.1.1json词法分析
        • 1.1.2json语法分析
    • 2.Gson的JsonElement
      • 2.1Json的JsonObject对象
      • 2.2JSON流程简图
      • 2.3JSON适配器模式
      • 2.4JSON整体流程
      • 2.5JSON反射机制
    • 3.打赏鼓励
      • 3.1微信打赏
      • 3.2支付宝打赏

1.Gson原理

在这个序列化和反序列化的过程中,Gson充当了一个解析器的角色。

在这里插入图片描述

1.1json分析

(1)编写一个JSON解析器实际上就是一个方法,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构

(2)一般来说,解析过程包括词法分析和语法分析两个阶段

在这里插入图片描述

1.1.1json词法分析

在这里插入图片描述

(1)源码:com.google.gson.stream.JsonToken

  • BEGIN_OBJECT({)
  • END_OBJECT(})
  • BEGIN_ARRAY([)
  • END_ARRAY(])
  • NULL(null)
  • NUMBER(数字)
  • STRING(字符串)
  • BOOLEAN(true/false)
  • SEP_COLON(:)
  • SEP_COMMA(,)

1.1.2json语法分析

在这里插入图片描述

n ➔ null
t ➔ true
f ➔ false
" ➔ string
0-9/- ➔ number
[ ➔ array
{ ➔ object

(1)json解析是基于事件驱动的

  • 需要的时候再加载到内存
  • 一个节点一个节点解析

(2)全量解析

  • 一次性加载到内存,然后解析

2.Gson的JsonElement

(1)该类是一个抽象类,代表着json串的某一个元素。
(2)这个元素可以是一个Json(JsonObject)、可以是一个数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个抽象类的子类。
(3)它代表的是词法分析出来的每一个元素
(4)它的实现类

在这里插入图片描述

在这里插入图片描述

2.1Json的JsonObject对象

(1)JsonObject对象可以看成 name/values的集合,而这些values就是一个个JsonElement,他们的结构可以用如下图表示

在这里插入图片描述

2.2JSON流程简图

在这里插入图片描述

2.3JSON适配器模式

在这里插入图片描述

(1)见com.google.gson.TypeAdapter的read与write方法

(2)在这里插入图片描述

任何一种数据类型的读写都有具体的TypeAdapter适配器与之对应。

(3)如果类型太多,需要自定义的TypeAdapter太多,则可考虑使用com.google.gson.internal.bind.ReflectiveTypeAdapterFactory解决

(4)com.google.gson.TypeAdapterFactory#create

根据不同的类型创建TypeAdapter

public interface TypeAdapterFactory {

  /**
   * Returns a type adapter for {@code type}, or null if this factory doesn't
   * support {@code type}.
   */
  <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
}

(5)com.google.gson.reflect.TypeToken#TypeToken()

  • 获取gson泛型 T 的类型
  • 通过反射去创建TypeAdapter
  protected TypeToken() {
    this.type = getSuperclassTypeParameter(getClass());
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
    this.hashCode = type.hashCode();
  }

2.4JSON整体流程

在这里插入图片描述

(1)Gson对象创建使用的是门面模式。
(2)而排除器使用的是代理模式
com.google.gson.internal.Excluder
(3)字段命名策略使用的是策略模式
com.google.gson.FieldNamingStrategy#translateName
(4)实例构造器
com.google.gson.internal.ConstructorConstructor
根据不同的数据类型返回一个构造器。

(5)TypeAdapter的工厂列表

List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();

决定json的解析顺序
jsonstr — > 排除器---->自定义TypeAdapter—>gson自带的TypeAdapter----> 反射ReflectiveTypeAdapterFactory解析。

(6)GsonBuilder的创建

  • 使用的是建造者模式
  • 最终通过create方法创建Gson对象出来

(7)toJson()
com.google.gson.Gson#toJson(java.lang.Object, java.lang.reflect.Type, com.google.gson.stream.JsonWriter)

  public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
    boolean oldLenient = writer.isLenient();
    writer.setLenient(true);
    boolean oldHtmlSafe = writer.isHtmlSafe();
    writer.setHtmlSafe(htmlSafe);
    boolean oldSerializeNulls = writer.getSerializeNulls();
    writer.setSerializeNulls(serializeNulls);
    try {
      ((TypeAdapter<Object>) adapter).write(writer, src);
    } catch (IOException e) {
      throw new JsonIOException(e);
    } catch (AssertionError e) {
      AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
      error.initCause(e);
      throw error;
    } finally {
      writer.setLenient(oldLenient);
      writer.setHtmlSafe(oldHtmlSafe);
      writer.setSerializeNulls(oldSerializeNulls);
    }
  }

(8)JsonWriter
写操作类

(9)fromJson

public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    boolean isEmpty = true;
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true);
    try {
      reader.peek();
      isEmpty = false;
      TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      T object = typeAdapter.read(reader);
      return object;
    } catch (EOFException e) {
      /*
       * For compatibility with JSON 1.5 and earlier, we return null for empty
       * documents instead of throwing.
       */
      if (isEmpty) {
        return null;
      }
      throw new JsonSyntaxException(e);
    } catch (IllegalStateException e) {
      throw new JsonSyntaxException(e);
    } catch (IOException e) {
      // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
      throw new JsonSyntaxException(e);
    } catch (AssertionError e) {
      AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
      error.initCause(e);
      throw error;
    } finally {
      reader.setLenient(oldLenient);
    }
  }

(10)JsonReader

  • com.google.gson.stream.JsonReader#doPeek

  • 将json从栈中取出进行词法分析

(11)getAdapter()

(12)调用TypeAdapter的read方法

2.5JSON反射机制

com.google.gson.internal.bind.ReflectiveTypeAdapterFactory#create

其他的解析器都没办法解析的时候,会使用这种反射的解析器来解析。

  @Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
    Class<? super T> raw = type.getRawType();

    if (!Object.class.isAssignableFrom(raw)) {
      return null; // it's a primitive!
    }

    ObjectConstructor<T> constructor = constructorConstructor.get(type);
    return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
  }
  private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
    Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
    if (raw.isInterface()) {
      return result;
    }

    Type declaredType = type.getType();
    while (raw != Object.class) {
      Field[] fields = raw.getDeclaredFields();
      for (Field field : fields) {
        boolean serialize = excludeField(field, true);
        boolean deserialize = excludeField(field, false);
        if (!serialize && !deserialize) {
          continue;
        }
        accessor.makeAccessible(field);
        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
        List<String> fieldNames = getFieldNames(field);
        BoundField previous = null;
        for (int i = 0, size = fieldNames.size(); i < size; ++i) {
          String name = fieldNames.get(i);
          if (i != 0) serialize = false; // only serialize the default name
          BoundField boundField = createBoundField(context, field, name,
              TypeToken.get(fieldType), serialize, deserialize);
          BoundField replaced = result.put(name, boundField);
          if (previous == null) previous = replaced;
        }
        if (previous != null) {
          throw new IllegalArgumentException(declaredType
              + " declares multiple JSON fields named " + previous.name);
        }
      }
      type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
      raw = type.getRawType();
    }
    return result;
  }

在这里插入图片描述

在这里插入图片描述
(1)解析的流程重要的部分都将其定义为TypeAdapter,即每一种类型与gson之间都会有一个TypeAdapter进行桥接。

(2)如果所有的TypeAdapter都不适配,会通过ReflectiveTypeAdapter去适配任意类型。

(3)拿到具体的typeAdapter

(4)拿到之后进行字符串的解析操作。

通过反射的方式去对字符串进行解析的时候,是拿到每一个field之后,通过递归操作运用反射去完成赋值。

3.打赏鼓励

感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!

3.1微信打赏

在这里插入图片描述

3.2支付宝打赏

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【26】Gson原理 的相关文章

随机推荐

  • IDEA Git 分支branch操作,新建和合并

    简单记录IDEA中Git分支操作 1 xff1a 创建分支 右下角new branch创建分支 创建完成查看右下角当前分支情况 创建一个该分支的MD文件信息 xff0c 进行提交 这样一个分支就创建完成 xff0c 然后merge分支 xf
  • KVM 介绍(1):简介及安装

    转载地址 xff1a http www cnblogs com sammyliu p 4543110 html KVM 介绍 xff08 1 xff09 xff1a 简介及安装 学习 KVM 的系列文章 xff1a xff08 1 xff0
  • 个人面试经验总结

    1 xff0c 海投 2 xff0c 一定要强调自己能留到该地 xff08 这个城市 这个公司 xff09 发展 3 xff0c 简历上出现的技能和项目面试前一天一定要复习 xff0c 因为面试官大部分问题会以简历为主 4 xff0c 要有
  • Java学习笔记4(设计模式、接口)

    设计模式 建造者模式 在类中 xff0c 定义一个静态内部类作为 外部类的 建造者在建造者类中 xff0c 提供多个 方法用来完成 外部类 对象的属性赋值在建造者类中 xff0c 提供一个 build 用来返回一个外部类的对象在类中 xff
  • R语言单因素/多因素 Logistic回归

    变量因子的转换 gt 单因素logistic回归 gt 多因素logistic回归 https mp weixin qq com s NowePGv6DF9 dF4blSyzVQ 两个模型的比较 构造测试集 xff0c 预测概率 xff0c
  • 那一年读过的技术经典书

    转载请注明 xff1a http blog csdn net xinzhangyanxiang article details 10199757 大学刚毕业 xff0c 总结起来读过的书并不算多 xff0c 而且主要集中在大四的时期读的 x
  • Bert: 双向预训练+微调

    最近要开始使用Transformer去做一些事情了 xff0c 特地把与此相关的知识点记录下来 xff0c 构建相关的 完整的知识结构体系 以下是要写的文章 xff0c 文章大部分都发布在公众号 雨石记 上 xff0c 欢迎关注公众号获取最
  • Federated Learning: 问题与优化算法

    工作原因 xff0c 听到和使用Federated Learning框架很多 xff0c 但是对框架内的算法和架构了解不够细致 xff0c 特读论文以记之 这个系列计划要写的文章包括 xff1a Federated Learning 问题与
  • DIN: 阿里点击率预估之深度兴趣网络

    广告推荐算法系列文章 xff1a 莫比乌斯 百度的下一代query ad匹配算法百度凤巢分布式层次GPU参数服务器架构DIN 阿里点击率预估之深度兴趣网络DIEN 阿里点击率预估之深度兴趣进化网络 本文的知识点来源于参考文献 1 xff0c
  • DIEN: 阿里点击率预估之深度兴趣进化网络

    广告推荐算法系列文章 xff1a 莫比乌斯 百度的下一代query ad匹配算法百度凤巢分布式层次GPU参数服务器架构DIN 阿里点击率预估之深度兴趣网络基于Delaunay图的快速最大内积搜索算法DIEN 阿里点击率预估之深度兴趣进化网络
  • 概率矩阵分解模型 PMF

    本文是论文 一种结合推荐对象间关联关系的社会化推荐算法 的笔记 xff08 上 xff09 因为对其中的概率矩阵分解 Probabilistic Matrix Factorization PMF 不够了解 xff0c 因而我先去脑补了PMF
  • 卷积神经网络

    卷积神经网络 转载请注明 xff1a http blog csdn net stdcoutzyx article details 41596663 自今年七月份以来 xff0c 一直在实验室负责卷积神经网络 xff08 Convolutio
  • DeepID人脸识别算法之三代

    DeepID人脸识别算法之三代 转载请注明 xff1a http blog csdn net stdcoutzyx article details 42091205 DeepID xff0c 目前最强人脸识别算法 xff0c 已经三代 如今
  • 理解dropout

    理解dropout 开篇明义 xff0c dropout是指在深度学习网络的训练过程中 xff0c 对于神经网络单元 xff0c 按照一定的概率将其暂时从网络中丢弃 注意是暂时 xff0c 对于随机梯度下降来说 xff0c 由于是随机丢弃
  • MYSQL— perror 错误码详情

    root 64 localhost cat test nothread py import paramiko import threading import os def ssh2 ip username passwd cmd file p
  • 深度卷积对抗生成网络(DCGAN)

    本文是参考文献 1 的论文笔记 卷积神经网络在有监督学习中的各项任务上都有很好的表现 xff0c 但在无监督学习领域 xff0c 却比较少 本文介绍的算法将有监督学习中的CNN和无监督学习中的GAN结合到了一起 在非CNN条件下 xff0c
  • 看图说话——CNN和LSTM的联合应用

    看图说话是深度学习波及的领域之一 其基本思想是利用卷积神经网络来做图像的特征提取 xff0c 利用LSTM来生成描述 但这算是深度学习中热门的两大模型为数不多的联合应用了 本文是参考文献 1 的笔记 xff0c 论文是比较早的论文 xff0
  • 机器学习经典书籍小结

    机器学习经典书籍小结 转载本博客请注明链接 xff1a http blog csdn net xinzhangyanxiang article details 9069045 博客第一篇文章 1 是转载的 xff0c 也算是开始写博客不经意
  • (一)Tensorflow图像数据转化TFRecord数据格式

    1 TFRecord数据格式 Tensorflow提供的TFRecord文件数据是通过tf train Example Protocol Buffer的格式存储的 数据格式 message Example Features features
  • 【26】Gson原理

    xff08 1 xff09 一个人只要自己不放弃自己 xff0c 整个世界也不会放弃你 xff08 2 xff09 天生我才必有大用 xff08 3 xff09 不能忍受学习之苦就一定要忍受生活之苦 xff0c 这是多么痛苦而深刻的领悟 x