日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android—Gson原理解析

發布時間:2023/12/18 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android—Gson原理解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JsonElement

  • 抽象類
  • 代表json串的某一個元素
  • 某一個元素:
    • JsonObject
    • JsonArray
    • JsonPrimitive(基本類型)
    • JsonNull

JsonElement的四個子類

  • JsonObject、JsonArray、JsonPrimitive、JsonNull

JsonPrimitive?

該類對Java的基本類型及其對應的對象類進行了封裝(短整長,單精雙精,字符<表示為單字符字符串>,布爾)

Gson對象的產生

通過new Gson()方式

?通過這種方式創建的Gson對象,將用Java的反射機制來完成json的解析,將大量默認的TypeAdapterFactory添加到factories中,生成默認的Gson對象

通過GsonBuilder的方式

TypeAdapter:該類的作用就是把json串封裝成你指定的Java對象

通過GsonBuilder注冊TypeAdapter,并把TypeAdapter封裝成TypeAdpterFactory對象

將封裝成的TypeAdapterFactory通過GsonBuilder的create傳入Gson對象中并返回

調用gson.fromJson方法,調用getTypeAdapter方法返回你自定義的Adapter

下面解析new?Gson()方式的序列化過程

String json = "{ \"name\":\"java書籍\", \"authors\":[\"Jerry\",\"Tom\"]}"; Book book = new Gson().fromJson(json, Book.class); String s = new Gson().toJson(book);public class Book implements Serializable {private String name;private ArrayList<String> authors;public Book(String name, ArrayList<String> authors) {this.name = name;this.authors = authors;} }

反序列化過程

public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {boolean isEmpty = true;// 接受不符合規定的json變量的值boolean oldLenient = reader.isLenient();//強制設置為接受reader.setLenient(true);try { //此處相當于調用了一次 JsonReader 中的 doPeek() 方法,返回下一個令牌的類型而不消耗它,設置當前令牌reader.peek();isEmpty = false;//TypeToken 本質上是 Class 的增強封裝類TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);//根據要轉化的實體類型,獲取相應的適配器TypeAdapter<T> typeAdapter = getAdapter(typeToken);//通過適配器生成實體類T object = typeAdapter.read(reader);return object;} catch (EOFException e) {.......}}

可以看到最終結果是adapter的read方法返回了我們需要的對象。
先看 getAdapter (typeToken) 方法:

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {// 先判斷緩存TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);if (cached != null) {return (TypeAdapter<T>) cached;}Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();boolean requiresThreadLocalCleanup = false;if (threadCalls == null) {threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();calls.set(threadCalls);requiresThreadLocalCleanup = true;}// the key and value type parameters always agreeFutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);if (ongoingCall != null) {return ongoingCall;}try {FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();threadCalls.put(type, call);//這里是重點,factories 是構建gson對象時候添加的類型適配器工廠值?for (TypeAdapterFactory factory : factories) {//循環尋找可以處理該類型的factory ,factory.create()很重要TypeAdapter<T> candidate = factory.create(this, type);if (candidate != null) {call.setDelegate(candidate);typeTokenCache.put(type, candidate);return candidate;}}throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type); }TypeAdapter<T> candidate = factory.create(this, type);根據type獲取相應的typeAdapter , 然后返回,new Gson()的話,在構造函數會給添加許多的adpter, Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,int timeStyle, List<TypeAdapterFactory> builderFactories,List<TypeAdapterFactory> builderHierarchyFactories,List<TypeAdapterFactory> factoriesToBeAdded) {this.excluder = excluder;this.fieldNamingStrategy = fieldNamingStrategy;this.instanceCreators = instanceCreators;this.constructorConstructor = new ConstructorConstructor(instanceCreators);this.serializeNulls = serializeNulls;this.complexMapKeySerialization = complexMapKeySerialization;this.generateNonExecutableJson = generateNonExecutableGson;this.htmlSafe = htmlSafe;this.prettyPrinting = prettyPrinting;this.lenient = lenient;this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;this.longSerializationPolicy = longSerializationPolicy;this.datePattern = datePattern;this.dateStyle = dateStyle;this.timeStyle = timeStyle;this.builderFactories = builderFactories;this.builderHierarchyFactories = builderHierarchyFactories;List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();// built-in type adapters that cannot be overriddenfactories.add(TypeAdapters.JSON_ELEMENT_FACTORY);factories.add(ObjectTypeAdapter.FACTORY);// the excluder must precede all adapters that handle user-defined typesfactories.add(excluder);// users' type adaptersfactories.addAll(factoriesToBeAdded);//添加factory// type adapters for basic platform typesfactories.add(TypeAdapters.STRING_FACTORY);factories.add(TypeAdapters.INTEGER_FACTORY);factories.add(TypeAdapters.BOOLEAN_FACTORY);factories.add(TypeAdapters.BYTE_FACTORY);factories.add(TypeAdapters.SHORT_FACTORY);TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));factories.add(TypeAdapters.newFactory(double.class, Double.class,doubleAdapter(serializeSpecialFloatingPointValues)));factories.add(TypeAdapters.newFactory(float.class, Float.class,floatAdapter(serializeSpecialFloatingPointValues)));factories.add(TypeAdapters.NUMBER_FACTORY);factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);factories.add(TypeAdapters.CHARACTER_FACTORY);factories.add(TypeAdapters.STRING_BUILDER_FACTORY);factories.add(TypeAdapters.STRING_BUFFER_FACTORY);factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));factories.add(TypeAdapters.URL_FACTORY);factories.add(TypeAdapters.URI_FACTORY);factories.add(TypeAdapters.UUID_FACTORY);factories.add(TypeAdapters.CURRENCY_FACTORY);factories.add(TypeAdapters.LOCALE_FACTORY);factories.add(TypeAdapters.INET_ADDRESS_FACTORY);factories.add(TypeAdapters.BIT_SET_FACTORY);factories.add(DateTypeAdapter.FACTORY);factories.add(TypeAdapters.CALENDAR_FACTORY);factories.add(TimeTypeAdapter.FACTORY);factories.add(SqlDateTypeAdapter.FACTORY);factories.add(TypeAdapters.TIMESTAMP_FACTORY);factories.add(ArrayTypeAdapter.FACTORY);factories.add(TypeAdapters.CLASS_FACTORY);// type adapters for composite and user-defined typesfactories.add(new CollectionTypeAdapterFactory(constructorConstructor));factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);factories.add(jsonAdapterFactory);factories.add(TypeAdapters.ENUM_FACTORY);factories.add(new ReflectiveTypeAdapterFactory(constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));this.factories = Collections.unmodifiableList(factories);}

因為我們采用的是new?Gson(),由于我們沒有添加自定義的Adapter,最后只能由ReflectiveTypeAdapterFactory進行處理。

直接看ReflectiveTypeAdapterFactory的create方法

@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {Class<? super T> raw = type.getRawType();//這里用于比對類型,如果不是相應的類型就返回null//確定此* {@code Class}對象表示的類或接口是否與指定的{{code code}}參數所表示的類或接口相同,或者是該類或接口的超類或父接口。 。如果是,則返回{@code true}; *否則返回{@code false}//很顯然,這里返回的是true 應為我們的類是TestMode 是一個class類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));}

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 nameBoundField 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; }

debug截圖:

?可以看到getBoundFields()方法結果返回的result是應該map對象,里面存著key為我們類屬性名,value為adapterFactory的對象。

了解了getAapter方法,我們接下來分析ReflectiveTypeAdapterFactory的read方法。

@Override public T read(JsonReader in) throws IOException {if (in.peek() == JsonToken.NULL) {in.nextNull();return null;}T instance = constructor.construct();try {in.beginObject();while (in.hasNext()) {String name = in.nextName();BoundField field = boundFields.get(name);if (field == null || !field.deserialized) {in.skipValue();} else {field.read(in, instance);}}} catch (IllegalStateException e) {throw new JsonSyntaxException(e);} catch (IllegalAccessException e) {throw new AssertionError(e);}in.endObject();return instance; }

?

這里的field就是剛剛getBoundFields()中獲取到的,放在map中的一個。

可以看到它調用的是field.read(in, instance);

return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException {Object fieldValue = field.get(value);TypeAdapter t = jsonAdapterPresent ? mapped : new TypeAdapterRuntimeTypeWrapper(context, mapped, fieldType.getType());((TypeAdapter)t).write(writer, fieldValue);}void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {Object fieldValue = mapped.read(reader);if (fieldValue != null || !isPrimitive) {field.set(value, fieldValue);}}

? ?根據debug截圖可以看出,fieldValue是typeAdapter調用read之后解析出來的值,就跟我們現在所跟的流程一樣,因為這里“java書籍“是String所以會到String對應的Adapter中解析,如果是我們自定義類的話還是會走再一遍反射。可以看到value是Book對象,

?都還是null,field對應的是name屬性,所以接下來set方法將fieldValue設置到Book對象的name屬性中。

?可以看到set方法后,book對象的name就有值了。

看下read方法最后返回的就是解析完成的對象,

序列化toJson同樣需要經過反射,

可以看ReflectiveTypeAdapterFactory的write方法,

@Override public void write(JsonWriter out, T value) throws IOException {if (value == null) {out.nullValue();return;}out.beginObject();try {for (BoundField boundField : boundFields.values()) {if (boundField.writeField(value)) {out.name(boundField.name);boundField.write(out, value);}}} catch (IllegalAccessException e) {throw new AssertionError(e);}out.endObject(); }

?它也是調boundField的方法,boundField.write(out, value);

@Override void write(JsonWriter writer, Object value)throws IOException, IllegalAccessException {Object fieldValue = field.get(value);TypeAdapter t = jsonAdapterPresent ? typeAdapter: new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());t.write(writer, fieldValue); }

?可以看到write之后,out屬性被寫上了“name“:”java書籍“。

?最終結果返回的是writer.toString()。

?

總結

以上是生活随笔為你收集整理的Android—Gson原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产又粗又黄又爽又硬的视频 | 亚洲一区二区三 | 久久九九色 | 欧美中文字幕视频 | 国产丝袜高跟 | 国产热99| 免费成人深夜夜行p站 | 久久久精品在线 | 美女打屁股网站 | 妖精视频在线观看 | 狠狠成人 | 播色网| a级片日本 | 免费的毛片网站 | 日韩国产欧美一区二区三区 | 做爰视频毛片视频 | 大陆女明星乱淫合集 | 99久久婷婷国产精品综合 | 亚洲第一欧美 | 久久无码专区国产精品s | 亚洲福利久久 | 欧美天堂 | 美日韩一区二区三区 | 日本不卡视频在线 | 美女草逼视频 | 对白刺激theporn | 国产又粗又猛又爽又黄av | 人妻精品一区一区三区蜜桃91 | 两性免费视频 | 婷婷tv | 性色视频 | 国产一区二区精品在线观看 | www成人免费视频 | 26uuu成人网 国产精品久久久久久久久久直播 | 亚洲一级二级片 | 久久精品中文字幕 | 亚洲热久久 | 精品美女在线观看 | 亚洲一区视频在线 | 91久久免费 | 久久久www成人免费精品 | 三级性生活片 | 日韩精品在线不卡 | 好大好舒服视频 | 国产黄色大片免费看 | 欧美va天堂 | 伊人成长网 | 91久久久久国产一区二区 | 六月丁香激情 | 女人做爰全过程免费观看美女 | av中文天堂在线 | 国产免费专区 | 精品视频一区二区在线观看 | 超碰97成人 | 亚洲一区二区美女 | 在线视频久久 | 亚洲天堂成人在线观看 | 在线免费看污网站 | 国产精品不卡一区 | 黄色一级网 | 亚洲精品专区 | 福利视频一区二区三区 | 中文字幕在线视频网 | 精品午夜福利视频 | 日韩av三级在线 | 色悠久久综合 | 人妖和人妖互交性xxxx视频 | 国产乱国产乱老熟300部视频 | 在线二区 | 丰满少妇xoxoxo视频 | 少妇视频一区二区三区 | 美女黄色在线观看 | 欧洲一区二区在线观看 | 狠狠躁夜夜 | 人妻在线一区二区三区 | 成人尹人| 亚洲狠狠婷婷综合久久久久图片 | 超碰v | 黄瓜污视频 | 免费黄色大片网站 | 男人操女人免费网站 | 黄视频在线播放 | 国产一伦一伦一伦 | 亚洲中文字幕一区二区 | 久久久最新 | 久久久噜噜噜久久中文字幕色伊伊 | 欧美激情啪啪 | 亚洲国产一区视频 | 日韩久久久精品 | xxxx毛片| 激情狠狠| 丝袜 亚洲 另类 国产 制服 | 国v精品久久久网 | 国产精品亚洲二区在线观看 | 日韩三级电影网址 | 久久久久一区二区精码av少妇 | 玖玖zyz| 奇米影视第四色首页 | 亚洲第一天堂影院 |