Gson 解析看這一篇就好

7,091 阅读8分钟

介绍

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。

基本概念

  • Serialization:序列化,使Java对象到Json字符串的过程。

  • Deserialization:反序列化,字符串转换成Java对象。

  • JSON数据中的JsonElement有下面这四种类型:

    JsonPrimitive -- JsonElement的子类,该类对Java的基本类型及其对应的包装类进行了封装,并通过setValue方法为value赋值。

    JsonObject -- json对象类,包含了键值对,键是字符串类型,值是一个JsonElement。用 LinkedTreeMap<String, JsonElement> members来保存。

    JsonArray -- Json的数组包含的其实也是一个个Json串,用List<JsonElement>来添加json数组中的每个元素

    JsonNull -- 不可变类

能解决的问题

  • 提供一种像toString()和构造方法的很简单的机制,来实现Java 对象和Json之间的互相转换。

  • 允许已经存在的无法改变的对象,转换成Json,或者Json转换成已存在的对象。

  • 允许自定义对象的表现形式

  • 支持任意的复杂对象

  • 能够生成可压缩和可读的Json的字符串输出。

Gson处理对象的几个要点

1 推荐把成员变量都声明称private的
2 没有必要用注解(@Expose 注解)指明某个字段是否会被序列化或者反序列化,所有包含在当前类(包括父类)中的字段都应该默认被序列化或者反序列化
3 如果某个字段被 transient 这个Java关键词修饰,就不会被序列化或者反序列化
4 下面的实现方式能够正确的处理null
1)当序列化的时候,如果对象的某个字段为null,是不会输出到Json字符串中的。
2)当反序列化的时候,某个字段在Json字符串中找不到对应的值,就会被赋值为null
5 如果一个字段是 synthetic的,他会被忽视,也即是不应该被序列化或者反序列化
6 内部类(或者anonymous class(匿名类),或者local class(局部类,可以理解为在方法内部声明的类))的某个字段和外部类的某个字段一样的话,就会被忽视,不会被序列化或者反序列化

常见的注解

@SerializedName注解 ---指定该字段在json中对应的字段名称

@SerializedName("companyId")
private String id;

@Expose注解 ---指定该字段是否能够序列化或者反序列化,默认的是都支持(true)

@Expose(serialize = false)
private String name;

@Since --- 自从

@Since(1.2) //从版本1.2之后才生效
private int shirtNumber;

@Until --- 一直到

@Until(0.9) //在0.9版本之前都是生效的
private String companyName;

Gson 序列化

Java类

public class Book {
  private String[] authors;
  private String isbn10;
  private String isbn13;
  private String title;
  //为了代码简洁,这里移除getter和setter方法等
}

希望的json数据

{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn-10": "032133678X",
  "isbn-13": "978-0321336781",
  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]
}

JSON数据中出现了isbn-10isbn-13, 我们怎么把字段数据isbn10isbn13转化为JSON数据需要的isbn-10isbn-13,Gson当然为我们提供了对应的解决方案。 1.@SerializedName注解

public class Book {
  private String[] authors;

  @SerializedName("isbn-10")
  private String isbn10;

  @SerializedName("isbn-13")
  private String isbn13;
  private String title;
  //为了代码简洁,这里移除getter和setter方法等

}

2.利用JsonSerializer

public class BookSerialiser implements JsonSerializer {

    @Override
    public JsonElement serialize(final Book book, final Type typeOfSrc, final JsonSerializationContext context) {
       
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("title", book.getTitle());
        jsonObject.addProperty("isbn-10", book.getIsbn10());
        jsonObject.addProperty("isbn-13", book.getIsbn13());

        final JsonArray jsonAuthorsArray = new JsonArray();
        for (final String author : book.getAuthors()) {
            final JsonPrimitive jsonAuthor = new JsonPrimitive(author);
            jsonAuthorsArray.add(jsonAuthor);
        }
        jsonObject.add("authors", jsonAuthorsArray);

        return jsonObject;
    }
}
  • JsonSerializer是一个接口,我们需要提供自己的实现,来满足自己的序列化要求。
public interface JsonSerializer<T> {

  public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);
}
  • 我们需要创建的是一个JsonElement对象,这里对应Book是一个对象,所以创建一个JsonObject类型。
  • 然后我们将相应字段里面的数据填充到jsonObject里面。
  • 所以最后返回的还是一个JsonElement 类型,这里对应的是jsonObject。完成了javaBean->JSON数据的转化。
  • gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser())方法进行JsonSerializer的配置。通过调用gsonBuilder.setPrettyPrinting();方法还告诉了 Gson 对生成的 JSON 对象进行格式化。
Gson gson = new GsonBuilder()
   .registerTypeAdapter(Book.class, new BookSerialiser())
   .enableComplexMapKeySerialization()
   .serializeNulls()
   .setDateFormat(DateFormat.LONG)
   .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
   .setPrettyPrinting()
   .setVersion(1.0)
   .create();

Gson 反序列化

json串

{
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "isbn-10": "032133678X",
  "isbn-13": "978-0321336781",
  "authors": [
    "Joshua Bloch",
    "Neal Gafter"
  ]
}

目标: Book对象

方案1: 利用@SerializedName 注解

public class Book {
  private String[] authors;

  @SerializedName("isbn-10")
  private String isbn10;

  @SerializedName(value = "isbn-13", alternate = {"isbn13","isbn.13"})
  private String isbn13;
  private String title;
  //为了代码简洁,这里移除getter和setter方法等

}

我们在@SerializedName 注解使用了一个value, alternate字段,value也就是默认的字段,对序列化和反序列化都有效,alternate只有反序列化才有效果。也就是说一般服务器返回给我们JSON数据的时候可能同样的一个图片,表示"image","img","icon"等,我们利用@SerializedName 中的alternate字段就能解决这个问题,全部转化为我们实体类中的图片字段。

方案二:使用JsonDeserializer

public class BookDeserializer implements JsonDeserializer<Book> {

  @Override
  public Book deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
      throws JsonParseException {
    final JsonObject jsonObject = json.getAsJsonObject();

    final JsonElement jsonTitle = jsonObject.get("title");
    final String title = jsonTitle.getAsString();

    final String isbn10 = jsonObject.get("isbn-10").getAsString();
    final String isbn13 = jsonObject.get("isbn-13").getAsString();

    final JsonArray jsonAuthorsArray = jsonObject.get("authors").getAsJsonArray();
    final String[] authors = new String[jsonAuthorsArray.size()];
    for (int i = 0; i < authors.length; i++) {
      final JsonElement jsonAuthor = jsonAuthorsArray.get(i);
      authors[i] = jsonAuthor.getAsString();
    }

    final Book book = new Book();
    book.setTitle(title);
    book.setIsbn10(isbn10);
    book.setIsbn13(isbn13);
    book.setAuthors(authors);
    return book;
  }
}
  • 通过final JsonObject jsonObject = json.getAsJsonObject();将我们的JsonElement转化为JsonObject
  • 通过jsonObject.get("xxx").getAsString()的形式获取相应String的值
  • 通过jsonObject.get("xx").getAsJsonArray();获取相应的json数组,并遍历出其中的相应字段值
  • 通过setter方法,将获取到的值设置给Book类。
  • 最终返回的是 Book的对象实例。完成了JSON->javaBean的转化
  • gsonBuilder.registerTypeAdapter(Book.class, new BookSerialiser())方法进行JsonSerializer的配置。
  • 从本地流中读取Json数据(可以使用 InputStreamReader完成)
  GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookDeserializer());
    Gson gson = gsonBuilder.create();

    // The JSON data
    try(Reader reader = new InputStreamReader(Main.class.getResourceAsStream("/part1/sample.json"), "UTF-8")){

      // Parse JSON to Java
      Book book = gson.fromJson(reader, Book.class);
      System.out.println(book);
    }

TypeAdapter介绍

image.png 我们在把Java对象转化为JSON字符串的时候都会用到这个中间件JsonElement,而TypeAdapter的使用正是去掉了这个中间层,直接用流来解析数据,极大程度上提高了解析效率。

TypeAdapter作为一个抽象类提供两个抽象方法。分别是write()read()方法,也对应着序列化和反序列化。

image.png

TypeAdapter的小demo

->> Book实体类

public class Book {

  private String[] authors;
  private String isbn;
  private String title;

//为了代码简洁,这里移除getter和setter方法等
}

->> BookTypeAdapter 具体序列化和反序列化的TypeAdapter

public class BookTypeAdapter extends TypeAdapter {

  @Override
  public Book read(final JsonReader in) throws IOException {
    final Book book = new Book();

    in.beginObject();
    while (in.hasNext()) {
      switch (in.nextName()) {
      case "isbn":
        book.setIsbn(in.nextString());
        break;
      case "title":
        book.setTitle(in.nextString());
        break;
      case "authors":
        book.setAuthors(in.nextString().split(";"));
        break;
      }
    }
    in.endObject();

    return book;
  }

  @Override
  public void write(final JsonWriter out, final Book book) throws IOException {
    out.beginObject();
    out.name("isbn").value(book.getIsbn());
    out.name("title").value(book.getTitle());
    out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
    out.endObject();
  }
}

->>注册

 final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Book.class, new BookTypeAdapter());
    final Gson gson = gsonBuilder.create();
JsonReader的作用

读取json字符串并转化为一个token流,而JsonParser就是根据这个token流进行json语法分析并转为java对象。

TypeToken

Java的泛型在运行时会有类型擦除,Gson解析将得不到预期的类型,TypeToken就是解决这个问题的。解决方案就是:匿名类+反射。

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();
}


static Type getSuperclassTypeParameter(Class<?> subclass) {
  Type superclass = subclass.getGenericSuperclass();
  if (superclass instanceof Class) {
    throw new RuntimeException("Missing type parameter.");
  }
  ParameterizedType parameterized = (ParameterizedType) superclass;
  return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}

原理就是用一个继承TypeToken的匿名类,从而获取该匿名类的泛型超类,然后将该泛型超类强制转换为ParameterizedType。ParameterizedType包含了获取其实际类型参数的方法getActualTypeArguments()及获取其原始类型的方法getRawType()。

public class TypeTokenTest {
//待解析的json字符串: {"data":"data from server"}
public class Response<T>{
    public T data;//简化数据, 省略了其他字段

    @Override
    public String toString() {
        return "Response{" +
                "data=" + data +
                '}';
    }
}

private Response<String> data;

public static void main(String[] args) {
    String json = "{\"data\":\"data from server\"}";

    //fromJson(String json, Class<T> classOfT)的第二个参数classOfT期望获取Response<String>这种类型
    //Class responseClass = Response<String>.class; /但是这么写不能通过编译,因为Response<String>不是一个Class类型
    Class responseClass = Response.class; //只能这样获取类型, 但无法知道Response里面数据的类型

    Response<String> result = (Response<String>) new Gson().fromJson(json, responseClass);
    System.out.println("result=" + result);

    //Gson的解决方案
    Type type = new TypeToken<Response<String>>(){}.getType();
    System.out.println("type=" + type);//TypeTokenTest$Response<java.lang.String>
    result = new Gson().fromJson(json, type);
    System.out.println("result=" + result);

 }
}

new TypeToken<Response>(){} 实例化的过程:

1. class TypeToken$0 extends TypeToken<Response<String>>{ } 
2. TypeToken typeToken = new TypeToken$0();

TypeToken0TypeToken<Response<String>>的匿名子类。所以typeTokenTypeToken0是TypeToken<Response<String>>的匿名子类。所以typeToken是TypeToken0类型的,父类型是TypeToken<Response>,而不是TypeToken,Type superclass = subclass.getGenericSuperclass(),得到的superclass 是TypeToken<Response>,而不是TypeToken。继续调用parameterized.getActualTypeArguments()[0] 得到的是Response

这也是为什么TypeToken的构造方法是protected的,想要调用该类的public方法不能够直接new一个TypeToken对象,可以新建一个匿名类(new TypeToken(){})或者新建一个类继承TypeToken来得到这个类的实例,然后调用该类的public方法

write方法
 public void write(final JsonWriter out, final Book book) throws IOException {
    out.beginObject();
    out.name("isbn").value(book.getIsbn());
    out.name("title").value(book.getTitle());
    out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
    out.endObject();
  }

传入JsonWriter,和需要被序列化的Book对象的实例,采用和PrintStream类似的方式 写入到JsonWriter中。

  • out.beginObject()产生{,如果我们希望产生的是一个数组对象,对应的使用beginArray()
public JsonWriter beginObject() throws IOException {
  writeDeferredName();
  return open(EMPTY_OBJECT, "{");
}
  • out.name("isbn").value(book.getIsbn()); out.name("title").value(book.getTitle());分别获取book中的isbn和title字段并且设置给Json对象中的isbn和title。
  • out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
  • out.endObject()则对应着}

最后的json

{
  "isbn": "978-0321336781",
  "title": "Java Puzzlers: Traps, Pitfalls, and Corner Cases",
  "authors": "Joshua Bloch;Neal Gafter"
}
read方法

传入一个JsonReader对象实例并返回反序列化的对象。

 public Book read(final JsonReader in) throws IOException {
    final Book book = new Book();

    in.beginObject();
    while (in.hasNext()) {
      switch (in.nextName()) {
      case "isbn":
        book.setIsbn(in.nextString());
        break;
      case "title":
        book.setTitle(in.nextString());
        break;
      case "authors":
        book.setAuthors(in.nextString().split(";"));
        break;
      }
    }
    in.endObject();

    return book;
  }
  • 同样是通过in.beginObject();in.endObject();对应解析{,}
  • 通过while循环遍历每一个JsonElement来给实体类设置对应的值
TypeAdapter的工作方式
  1. 通过GsonBuilder注册TypeAdapter,并把TypeAdapter封装成TypeAdpterFactory对象
  2. 将封装成的TypeAdapterFactory通过GsonBuilder的create方法传入Gson对象中
  3. 调用gson.fromJson方法,调用getAdapter方法返回自定义的Adapter,并调用其reader方法将json转为java对象
TypeAdapterFactory

在Gson中有大量的TypeAdapterFactory,比如基本类型都对应一个TypeAdapter,每个TypeAdapter都对应一个TypeAdapterFactory

public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
  @Override
  public Number read(JsonReader in) throws IOException {
    if (in.peek() == JsonToken.NULL) {
      in.nextNull();
      return null;
    }
    try {
      return in.nextInt();
    } catch (NumberFormatException e) {
      throw new JsonSyntaxException(e);
    }
  }
  @Override
  public void write(JsonWriter out, Number value) throws IOException {
    out.value(value);
  }
};
public static final TypeAdapterFactory INTEGER_FACTORY
    = newFactory(int.class, Integer.class, INTEGER);

public static final TypeAdapter<AtomicInteger> ATOMIC_INTEGER = new TypeAdapter<AtomicInteger>() {
  @Override public AtomicInteger read(JsonReader in) throws IOException {
    try {
      return new AtomicInteger(in.nextInt());
    } catch (NumberFormatException e) {
      throw new JsonSyntaxException(e);
    }
  }

自定义TypeAdapter实际上就是先转换成TypeAdapterFactory然后在Gson的getAdapter方法中遍历TyperAdapterFactory,并调用create方法得到TypeAdapter

public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
  factories.add(factory);
  return this;
}

在new Gson()这个Gson默认构造器的时候,其实调用了另外一个带参数的构造器进行初始化

public Gson() {
  this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
      Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
      DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
      DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
      LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT, DateFormat.DEFAULT,
      Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
      Collections.<TypeAdapterFactory>emptyList());
}

带有参数的构造器的的其中一个作用就是为Gson对象的 factories 添加大量的Gson自带的TypeAdapterFactory:

// users' type adapters
factories.addAll(factoriesToBeAdded);

// type adapters for basic platform types
factories.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 types
factories.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);

添加TypeAdapterFactory的顺序是先添加 用户自定义的TypeAdapterFactory,然后添加 Gson自带的TypeAdapterFactory,最后添加ReflectiveTypeAdapterFactory。Gson解析的时候也是根据这个顺序来获取TypeAdapterFactory的

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {

	...

	try {
		FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
		threadCalls.put(type, call);

		for (TypeAdapterFactory factory : factories) {
			TypeAdapter<T> candidate = factory.create(this, type);
			if (candidate != null) {
				call.setDelegate(candidate);
				typeTokenCache.put(type, candidate);
				return candidate;
			}
		}

	...


}

getAdapter方法会遍历factories,根据type去获取TypeAdapterFactory,for循环中只要TypeAdapterFactory.create返回的TypeAdapter!=null 则返回创建的TypeAdapter,用该TypeAdapter解析json,因为用户自定义的TypeAdapterFactory和Gson自带的TypeAdapterFactory位置在factories的前面,优先于ReflectiveTypeAdapterFactory遍历到,所以就避免了用Gson的反射机制来解析json了。

20200802193704666.png

ReflectiveTypeAdapterFactory

调用ReflectiveTypeAdapterFactory的create方法,返回一个ReflectiveTypeAdapterFactory.Adapter对象

@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));
}
ObjectConstructor

ObjectConstructor构造器对象用于Adapter在解析json时进行构造对象。而这个ObjectConstructor是来自于一个constructorConstructor的对象,ConstructorConstructor即构建构造器的意思,即用于创建ObjectConstructor构造器对象。

constructorConstructor在构造时,传入了一个instanceCreators对象,这个对象是一个享元对象。默认的情况下,这个对象为空,如果你有自己构造一个对象的需求,可以注入这个对象。那么,Gson会优先选择你注入的这个对象构造器来改造最终对象,我们来看下ConstructorConstructor的ObjectConstructor get(TypeToken typeToken)方法:

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
        final Type type = typeToken.getType();
        final Class<? super T> rawType = typeToken.getRawType();

		//先通过type去获取InstanceCreator,如果获取到InstanceCreator,则通过它来创建构造器对象
        // first try an instance creator

        @SuppressWarnings("unchecked") // types must agree
        final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
        if (typeCreator != null) {
            return new ObjectConstructor<T>() {
                @Override public T construct() {
                    return typeCreator.createInstance(type);
                }
            };
        }
			
		//再通过rawType去获取InstanceCreator,如果获取到InstanceCreator,则通过它来创建构造器对象
        // Next try raw type match for instance creators
        @SuppressWarnings("unchecked") // types must agree
        final InstanceCreator<T> rawTypeCreator =
                (InstanceCreator<T>) instanceCreators.get(rawType);
        if (rawTypeCreator != null) {
            return new ObjectConstructor<T>() {
                @Override public T construct() {
                    return rawTypeCreator.createInstance(type);
                }
            };
        }
		
		//如果是普通类,将使用newDefaultConstructor方法创建一个默认的构造器对象
        ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
        if (defaultConstructor != null) {
            return defaultConstructor;
        }

		//如果是接口类,将通过newDefaultImplementationConstructor方法创建一个默认的构造器对象
        ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
        if (defaultImplementation != null) {
            return defaultImplementation;
        }

		//如果自定义的java类中没有默认构造器,那么最终会调用newUnsafeAllocator方法来为你创建对应的Java对象
        // finally try unsafe
        return newUnsafeAllocator(type, rawType);
    }


  private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
    try {
     //此方法返回具有指定参数列表的构造函数对象,在这里没有传参数,即获取默认的构造器
      final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
      if (!constructor.isAccessible()) {
        accessor.makeAccessible(constructor);
      }
      return new ObjectConstructor<T>() {
        @SuppressWarnings("unchecked") // T is the same raw type as is requested
        @Override public T construct() {
          try {
            Object[] args = null;
            return (T) constructor.newInstance(args);  //创建Java对象,并返回
          } catch (InstantiationException e) {
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args", e);
          } catch (InvocationTargetException e) {
            // TODO: don't wrap if cause is unchecked!
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args",
                e.getTargetException());
          } catch (IllegalAccessException e) {
            throw new AssertionError(e);
          }
        }
      };
    } catch (NoSuchMethodException e) {
      return null;
    }
  }
getBoundFields方法
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;
}


private ReflectiveTypeAdapterFactory.BoundField createBoundField(
        final Gson context, final Field field, final String name,
        final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
        
    final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
    // special casing primitives here saves ~5% on Android...
    JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
    TypeAdapter<?> mapped = null;
    if (annotation != null) {
        mapped = jsonAdapterFactory.getTypeAdapter(
                constructorConstructor, context, fieldType, annotation);
    }
    final boolean jsonAdapterPresent = mapped != null;
    if (mapped == null) mapped = context.getAdapter(fieldType);

    final TypeAdapter<?> typeAdapter = mapped;
    return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
        
        @SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
        @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);
        }
        
        @Override
        void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {
        	//根据这个字段对应的Type获取对应的TypeAdapter,调用TypeAdapter的read读取fieldValue
            Object fieldValue = typeAdapter.read(reader);
            if (fieldValue != null || !isPrimitive) {
                field.set(value, fieldValue);//给field设置fieldValue
            }
        }
        
        @Override
        public boolean writeField(Object value) throws IOException, IllegalAccessException {
            if (!serialized) return false;
            Object fieldValue = field.get(value);
            return fieldValue != value; // avoid recursion for example for Throwable.cause
        }
        
    };
}

BoundField这个类的用途是将字段的名称和Field进行绑定,字段的名称可能是字段名或者是通过注解定义的名称。

Gson用ReflectiveTypeAdapterFactory通过反射解析json ,核心原理简而言之就是通过反射创建Java对象,循环遍历该对象的Field,并通过Field的set(Object,value)方法来对Java对象的Field赋值。 步骤:

  • 获取type对应的默认构造器
  • 通过Constructor的newInstance()来创建一个type类型的Java对象
  • 解析json的键值对,获取key和value,
  • 获取key对应的Field,通过Field的set(Object, value)方法设置value

小结

Gson解析成Java对象的实现原理:

1)注册自定义的或者Gson自己定义的TypeAdapter 
2)将TypeAdapter封装成TypeAdapterFactory,并把此Factory添加到Gson的factories(List)中 
3)通过fromJson方法最终调用getAdapter,遍历factories,获取fromJson的第二个参数type与之对应的TypeAdapterFactory,调用该Factory的create方法来创建一个TypeAdapter 
4)调用TypeAdapter的read方法完成json到Java Object的转换。