JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名。 JSON是一个序列化的对象或数组。
语法规则,是解析和生成的主要依据,Gson库在JsonReader类依据此来解析数据的,在JsonWriter中依据这个来写数据的
是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象;主要有以下概念,这些概念与gson格式特点对应
dependencies { implementation 'com.google.code.gson:gson:x.x.x' } 复制代码
// 使用new方法 Gson gson = new Gson(); // toJson 将bean对象转换为json字符串 String jsonStr = gson.toJson(user, Xxx.class); // fromJson 将json字符串转为bean对象 Student user= gson.fromJson(jsonStr, Xxx.class); 复制代码
这是一个序列化、反序列化json格式数据的库;它可以分为
java对象通过TypeAdapter适配器写到JsonWriter中,JsonWriter负责具体的格式书写
json数据通过进行包装,具体由JsonReader执行识别操作,通过TypeAdapter适配生成类对象
TypeAdapter类适配器作用,类和json解析出数据的桥梁;其中包括对象生成,成员变量解析、赋值
JsonWriter负责json格式字符串生成
JsonReader负责json格式字符串,解析成键值对或者单个值
从代码角度来说使用了适配器模式,这个是核心模式;而其中又参杂了建造者模式、静态代理模式、策略模式、抽象工程模式等;有兴趣的可以具体去找找这些模式
按照json格式规则进行读取
其它一些方法,比如略过标记符、空白符等
按照json格式规则进行写入
还有一些按照数据类别写入标记符,空白符
抽象类,其内部方法fromJson、toJson等方法通过read、write抽象方法来实现
public abstract void write(JsonWriter out, T value) throws IOException; public abstract T read(JsonReader in) throws IOException; 复制代码
这两个方法实现了具体类型的读取写入过程
这个可以分为以下几种
在这里,我们就分析下前四种,后面一种,由于没有用过,不是清楚什么类型,理解起来有点难度;
这些是单值类型,作为数组或者集合的元素;也可以作为map或者java bean中的value类型,如果是字符串类型,也可以作为key类型
Class类型,json数据不接受;read,write实现直接报异常
public static final TypeAdapter<Class> CLASS = new TypeAdapter<Class>() { @Override public void write(JsonWriter out, Class value) throws IOException { throw new UnsupportedOperationException("Attempted to serialize java.lang.Class: " + value.getName() + ". Forgot to register a type adapter?"); } @Override public Class read(JsonReader in) throws IOException { throw new UnsupportedOperationException( "Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?"); } }.nullSafe(); 复制代码
String类型,代码就是把字符串读出,写入
public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() { @Override public StringBuilder read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } return new StringBuilder(in.nextString()); } @Override public void write(JsonWriter out, StringBuilder value) throws IOException { out.value(value == null ? null : value.toString()); } }; 复制代码
URL数据,写入时,写的是String,读取时也是String,不过再加了转换
public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() { @Override public URL read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } String nextString = in.nextString(); return "null".equals(nextString) ? null : new URL(nextString); } @Override public void write(JsonWriter out, URL value) throws IOException { out.value(value == null ? null : value.toExternalForm()); } }; 复制代码
其它也有一些,都是通过转化成基本数据或者string类型来读取和写入的;
代码在MapTypeAdapterFactory中,比较多,就不列出来了,大致流程:
代码在ReflectiveTypeAdapterFactory中,比较多,就不列出来了,大致流程:
代码在CollectionTypeAdapterFactory中,比较多,就不列出来了,大致流程
ObjectConstructor接口 数组、集合、map、普通类生成实例的 Excluder、FieldNamingStrategy,解析的策略类 LongSerializationPolicy,序列化值类
文章中对具体TypeAdatpter并没有进行详细的代码流程分析;JsonReader,JsonWriter也没有进行详细的代码流程分析;这是因为,对于框架或者库的理解,首先要理解流程和原理,然后才是细节的处理;作者在这里只想作为进入Gson的辅助文章;更多的细节内容是硬知识,需要自己花费功夫去理解和记忆。
技术变化都很快,但基础技术、理论知识永远都是那些;作者希望在余后的生活中,对常用技术点进行基础知识分享;如果你觉得文章写的不错,请给与关注和点赞;如果文章存在错误,也请多多指教!
很遗憾的说,推酷将在这个月底关闭。人生海海,几度秋凉,感谢那些有你的时光。
原文 https://juejin.im/post/5f18d56b6fb9a07e9824e978